为啥在为接口创建实例时它可以在 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 看看这个,也许你可以使用这个例子来解决你的情况 你能再检查一下你的代码吗?您的问题使用IAgilent34980A
、Agilent34980
和Agilent34980A
,我不确定这是问题的一部分还是只是错字。列出这三种类型在 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 中却说在我提供时缺少提供?