日期:2014-05-17  浏览次数:21326 次

接口不能实例化?
 IEngineFeatureSnapAgent featureSnapAgent = new EngineFeatureSnap();

虽然明明知道,接口是不能实例化的,但是我今天又看到了将接口new的语句,而且代码可以正常运行,没有任何错误。第一次见到将接口new是在将datagridview里的数据导入excel里时:

            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
而且也能正常运行。

真是搞不懂,明明接口不能实例化,那为什么却能像实例化类一样实例化接口呢???而且完全正常使用。这到底是“实例化”吗??

------解决方案--------------------
那是 COM 包装过了的。。。和托管对象不一样。
------解决方案--------------------
COM的接口是通过包装实例化,.net 做了些翻译。

Microsoft.Office.Interop.Excel 的定义:
public interface Application : _Application, AppEvents_Event


http://msdn.microsoft.com/zh-cn/library/microsoft.office.interop.excel.application.aspx

[CoClass(typeof(ApplicationClass))]
[Guid("000208D5-0000-0000-C000-000000000046")]
public interface Application : _Application, AppEvents_Event
{
}
------解决方案--------------------
因为EngineFeatureSnap类 实现了 IEngineFeatureSnapAgent 接口。
通过 IEngineFeatureSnapAgent featureSnapAgent = new EngineFeatureSnap(); 这句话 对象featureSnapAgent 就可以 调用接口IEngineFeatureSnapAgent 里定义的方法和属性了。
如果这个类 还实现了别的接口 那么可以通过query interface 调用别的接口的方法和属性了。

------解决方案--------------------
引用:
COM的接口是通过包装实例化,.net 做了些翻译。

Microsoft.Office.Interop.Excel 的定义:
C# code
public interface Application : _Application, AppEvents_Event


http://msdn.microsoft.com/zh-cn/library/microsoft.office.i……


所以实例化的是 ApplicationClass
------解决方案--------------------
而且通过接口来实例化对象 这个也是多态的表现。
PS 
实现接口的类 实例 = new 实现接口的类()
------解决方案--------------------
接口 实例 = new 实现接口的类A() 
接口 实例 = new 实现接口的类B() 
接口 实例 = new 实现接口的类C() 
这样的逻辑就是说,我们需要某个类,所以我们每次实例化它。

如果把 ABC这三个类,再用一个类封D装起来,会怎么样呢?

接口 实例 = D.A
接口 实例 = D.B
接口 实例 = D.C

我们还是需要某个类,但是,我们不需要每次都实例化了,只需要找D“拿”就行
------解决方案--------------------
同理啊,所有COM的Interface另当别论了。


------解决方案--------------------
.NET提供Interop 程序集,它用作托管和非托管代码之间的桥梁,将 COM 对象成员映射为等价的 .NET 托管成员。
------解决方案--------------------
对于原有的Com文件,比如ABC.dll
当你在.net 环境下引用的时候,你会发现,实际引用的文件是Interop.ABC.dll
这正是由于.net在中间做了处理,将原来的ABC.dll翻译为了.Net可以识别的元数据清单