如何初始化一个接口?
如何初始化一个接口?
目前为止我学到的是我们不能创建接口的实例。
接口IFood定义如下:
interface IFood
{
string Color { get; set; }
}
类Apple实现了IFood接口:
class Apple : IFood
{
public string Color { get ; set; }
}
代码中的语句IFood food = new IFood();会编译错误。
而语句IFood food = new Apple();则可以正常运行。
到目前为止一切都还好。但是当我使用Microsoft.Office.Interop.Excel时,我发现像下面这样的东西:
Application是一个接口,但是下面的代码可以正常运行:
Application excel = new Application();
我在这里漏掉了什么?
如何初始化一个接口是可能的?
这个问题的出现是因为在COM中是一个Interop的能力。
Microsoft.Office.Excel API包括Application类,是用C++编写的。
由于C++中的架构更加自由,在某些情况下需要初始化一个接口。
.NET使用CoClass属性在COM对象上来解决初始化接口的问题。
C#不允许初始化一个接口,但是通过CoClass属性,接口的初始化可以被路由到CoClass类。
所以让我们来复现这个解决方法:
[CoClass(typeof(SugarGlider))] [ComImport] //假装是一个COM类 [Guid("000208D5-0000-0000-C000-000000000046")] //随便放一个GUID来愚弄ComImport public interface ISquirrel { string Foo(); } [ClassInterface(ClassInterfaceType.None)] public class SugarGlider : ISquirrel { public string Foo(){ return "Bar"; } }
现在你可以通过`new ISquirrel()`来初始化接口了。
完整的例子并且可以在线运行:[https://rextester.com/ORAZQ51751](https://rextester.com/ORAZQ51751)
在COM(Component Object Model)中,使用CoClass属性来初始化接口是可能的。通过使用CoClass属性,可以告诉编译器该接口将由Application类实现,并允许通过实例化接口来进行初始化。
解决方法:
1. 在接口定义中添加CoClass属性,并指定实现该接口的类(比如Application类)。
[CoClass(typeof(Application))]
public interface IMyInterface
{
// 接口定义
}
2. 创建一个类(比如Application类),并实现该接口。
[ComVisible(true)]
public class Application : IMyInterface
{
// 接口实现
}
3. 使用CoClass属性初始化接口。
IMyInterface myInterface = new IMyInterface();
通过以上步骤,我们可以使用CoClass属性来初始化接口,使其通过实例化来实现。这样可以简化接口的初始化过程,并提供更方便的接口调用方式。
初始化一个接口的问题出现的原因是因为接口本身无法被实例化,需要通过CoClass属性来指示接口由哪个类来实现。这样编译器就可以推断要实例化的类是什么。
解决方法是在接口上应用CoClass属性,声明该接口由哪个类来实现。这样,使用接口的时候就可以直接实例化类,而不是接口本身。
下面的代码演示了如何使用CoClass属性来初始化一个接口:
[CoClass(typeof(ApplicationClass))] public interface Application { // Interface methods and properties } public class ApplicationClass : Application { // Implementation of Application interface } // Usage Application excel = new Application();
通过上述代码,我们使用CoClass属性将Application接口指示为由ApplicationClass类来实现。在使用接口的时候,我们可以直接实例化ApplicationClass类,而不是接口本身。这样就解决了无法初始化接口的问题。
参考资料:
- [What does the C# CoClass attribute do?](https://stackoverflow.com/questions/6960910)
- [How does the C# compiler detect COM types?](https://stackoverflow.com/questions/1093536)