为啥在为接口创建实例时它可以在 C# 中工作?

Posted

技术标签:

【中文标题】为啥在为接口创建实例时它可以在 C# 中工作?【英文标题】:Why it works in C# when creating instance for an interface?为什么在为接口创建实例时它可以在 C# 中工作? 【发布时间】:2013-01-22 08:36:00 【问题描述】:

编辑:我找到了关于 C# 和 COM 的相关页面:How does the C# compiler detect COM types?

如标题所示,当我将 C# 程序转换为 IronPython 时,我无法创建类的实例。

C#原程序:IAgilent34980A2 host = new Agilent34980A();

重写的 IronPython 程序:host = Agilent34980A()

C# 程序运行良好,而 IronPython 程序出现以下错误:

TypeError:无法创建 Agilent34980A 的实例,因为它是抽象的

其实Agilent34980A()是一个接口,所以报错是合理的。

我的问题是 为什么它在 C# 中有效?实例也不能在 C# 中创建,它是一个接口,对吧?

加法:

C# 代码来自测试机标记。

IAgilent34980A2源代码定义部分如下:

使用 Ivi.Driver.Interop;

使用系统;

使用 System.Runtime.InteropServices;

命名空间 Agilent.Agilent34980A.Interop

  //     IAgilent34980A interface.

[TypeLibType(256)]
[Guid("07678A7D-048A-42A6-8884-6CC8C575BD1F")]
[InterfaceType(1)]
public interface IAgilent34980A2 : IIviDriver

   IAgilent34980AMeasurement Measurement  get; 
   IAgilent34980AVoltage Voltage  get; 
  //  There are some similar functions following.

Agilent34980A 定义部分

使用 System.Runtime.InteropServices;

命名空间 Agilent.Agilent34980A.Interop

  //     Agilent34980A driver class.
[Guid("07678A7D-048A-42A6-8884-6CC8C575BD1F")]
[CoClass(typeof(Agilent34980AClass))]
public interface Agilent34980A : IAgilent34980A2


和IIviDriver定义部分

使用系统;

使用 System.Runtime.InteropServices;

命名空间 Ivi.Driver.Interop

//     IVI Driver root interface
[TypeLibType(256)]
[InterfaceType(1)]
[Guid("47ED5184-A398-11D4-BA58-000064657374")]
public interface IIviDriver

   //     Pointer to the IIviDriverOperation interface
   [DispId(1610678272)]
   IIviDriverOperation DriverOperation  get; 
   
   //     Pointer to the IIviDriverIdentity interface
   [DispId(1610678273)]
   IIviDriverIdentity Identity  get; 
   //  There are some similar functions following.

【问题讨论】:

IronPython 是否支持接口..?听起来您需要寻找 IronPython 专家 谢谢你,DJ KRAZE。正如你所说,我应该找一个 IronPython 专家。但在此之前,我真的不明白为什么它在 C# 中运行良好,虽然 Agilent34980() 是一个接口。 How to use a specific interface on a C# object in IronPython 看看这个,也许你可以使用这个例子来解决你的情况 你能再检查一下你的代码吗?您的问题使用IAgilent34980AAgilent34980Agilent34980A,我不确定这是问题的一部分还是只是错字。列出这三种类型在 c# 中的定义。 基于通用命名约定 IAgilent34980A host = new Agilent34980(); IAgilent34980A --> 接口 Agilent34980 --> 实现该接口的类。这在 C# 中是完全合法的。您不是在创建接口对象,而是创建实现该接口的类的对象 【参考方案1】:

实际上,您可以通过具有[CoClass][Guid] 属性的co-class 创建一个接口实例。

这让你可以:

[Guid("000208D5-0000-0000-C000-000000000046")] // Anything
[CoClass(typeof(Foo))]
[ComImport]
public interface IFoo  void Bar(); 

public class Foo : IFoo  public void Bar()  return;  

void Main()

    IFoo instance = new IFoo();

【讨论】:

-1:错误 CS0144:无法创建抽象类或接口“IFoo”的实例 +1 now ;p 添加缺失位,现在可以编译。有趣的;p C# 编译器将new IFoo() 替换为new Foo() 感谢您的回复。我将接口定义部分编辑到我的消息中。 “Agilent34980A()”被定义为一个接口。 @shihuan83:解决方案是实例化Agilent34980AClass或使用Marshall类中的方法。【参考方案2】:

您不能在 C# 中创建接口的实例。 示例代码:

void Main()

    var test = new ITest();


interface ITest 
    void Test();

会报编译错误:

Cannot create an instance of the abstract class or interface "UserQuery.ITest"

问题只是你的类没有正确声明为库中的接口。

代码如下:

IAgilent34980A host = new Agilent34980();

有效,因为它意味着“变量'主机'是对某个对象的引用,该对象是实现 IAgilent34980A 接口的类的实例”。 C# 非平凡对象是引用类型,因此这是有效的。

【讨论】:

从表面上看,他/她不是试图在 C# 中创建一个接口实例,而是一个实现接口的类实例 - cf。 IAgilent34980A host = new Agilent34980(); 不,这不是创建接口的实例。他正在实例化一个类(Agilent34980),而不是接口。然后他将这个类分配给这个接口的一个变量(主机),所以这个类必须实现这个接口,它似乎是这样做的(没有编译器错误)。 好吧,在我看来,作者认为这实际上是他正在实例化的接口。我在解释实例化一个接口真的是不可能的,并详细说明实际发生的事情(见编辑的答案) 感谢您的回复。我将接口定义部分编辑到我的消息中。 “Agilent34980A()”被定义为一个接口。

以上是关于为啥在为接口创建实例时它可以在 C# 中工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥匕首图可以在 java 中工作,但在 Kotlin 中却说在我提供时缺少提供?

C#为啥接口可以实例化一个实现该接口的类?

EL 空运算符如何在 JSF 中工作?

执行器端点如何在集群环境中工作

为啥 Task.Delay 不能在 Azure Function App 中工作?

为啥 PyAudio 在一个模块中工作而不是在另一个模块中工作?