new 一个接口?
如果有人问你,C# 中可以new 一个接口吗?,你会怎么回答?
假设ITestInte易做图ce 是一个接口,那么这样的代码是否有问题?
ITestInte易做图ce testInte易做图ce = new ITestInte易做图ce();
很多书上都会说,当然有问题,接口不能用new ,然后你就认为上面这句语句肯定通不过编译器的编译了。
可是凡事无绝对,C# 竟然允许你这么写,当然你需要加点”料”才行。
在VS2005 中新建控制台程序CA2005.添加 Microsoft.Office.Interop.Excel 引用
Program 的Main函数只有一句话:
注意,可以通过编译,看下Application的定义:
很明显Application 是个inte易做图ce,
这里我要扯一下,经常看到有人说string 是类还是结构什么的,看下string 的定义:
String 是用class 来修饰的,所以string 100% 是类。
还是扯回来吧,Application 是个接口,但是我们却可以用new .为什么 ?
先看下反编译后的代码吧:
可以看到虽然我们写的是new Application,但是编译器为我们生成的却是new ApplicationClass();
难道Application 有什么特别的地方?
仔细的同学一眼就看出了Application是被这两个特性修饰的:
[CoClass(typeof(ApplicationClass))]
[Guid("000208D5-0000-0000-C000-000000000046")]
关于CoClass的解释可以看msdn:
有些人不喜欢看msdn,而喜欢看博客的一个原因就是msdn太不直白了。
我个人的理解是CoClass 就好像concrete Class(具体类)。
这个特性指示编译器在编译Application的时候,使用ApplicationClass 来实现。
回到上面的最初的问题上:
如何让这段代码通过编译:
ITestInte易做图ce testInte易做图ce = new ITestInte易做图ce();
通过上面的分析,我们很容易将这个特性来修饰我们的自己的接口:
namespace CA2005
{
[CoClass(typeof(TestClass))]
[Guid("6C8BF7FE-1F6B-437E-BCC8-6D2FF04E66B3")]
public inte易做图ce ITestInte易做图ce
{
void DoSomething();
}
[Guid("68C7CB18-0DEE-4689-845D-741525281C76")]
public class TestClass : ITestInte易做图ce
{
public void DoSomething()
{
Console.WriteLine("TestClass:DoSomething");
}
}
class Program
{
static void Main(string[] args)
{
Microsoft.Office.Interop.Excel.Application excelApplication =
new Microsoft.Office.Interop.Excel.Application();
ITestInte易做图ce testInte易做图ce = new ITestInte易做图ce();
testInte易做图ce.DoSomething();
}
}
}
编译,结果如下:
接口被标记了CoClassAttribute,而不是ComImportAttribute.
原来想要new 一个接口使用的是编译器对COM的优化和支持。
很明显上面的Application是一个COM对象,所以可以new Application
在ITestApplication中添加ComImportAttribute 特性:
再次运行,结果如下:
查看下反编译的代码:
之所以我对VS2005 用红色字体,是因为如果你用VS2010 创建的程序,那么你会看到不一样的反编译结果:
public static void Main()
补充:软件开发 , C# ,