当前位置:编程学习 > C#/ASP.NET >>

new 一个接口?

如果有人问你,C# 中可以new 一个接口吗?,你会怎么回答?

 


假设ITestInterface 是一个接口,那么这样的代码是否有问题?


ITestInterface testInterface = new ITestInterface();


很多书上都会说,当然有问题,接口不能用new ,然后你就认为上面这句语句肯定通不过编译器的编译了。

 

可是凡事无绝对,C# 竟然允许你这么写,当然你需要加点”料”才行。

 

在VS2005 中新建控制台程序CA2005.添加 Microsoft.Office.Interop.Excel 引用

 image

image

Program 的Main函数只有一句话:

 image

注意,可以通过编译,看下Application的定义:

 image

很明显Application 是个interface,

这里我要扯一下,经常看到有人说string 是类还是结构什么的,看下string 的定义:

 image

String 是用class 来修饰的,所以string 100% 是类。


还是扯回来吧,Application 是个接口,但是我们却可以用new  .为什么 ?


先看下反编译后的代码吧:

 image

可以看到虽然我们写的是new Application,但是编译器为我们生成的却是new ApplicationClass();


难道Application 有什么特别的地方?

 

仔细的同学一眼就看出了Application是被这两个特性修饰的:

 

[CoClass(typeof(ApplicationClass))]

 

[Guid("000208D5-0000-0000-C000-000000000046")]

 

关于CoClass的解释可以看msdn:

 image

有些人不喜欢看msdn,而喜欢看博客的一个原因就是msdn太不直白了。

 


我个人的理解是CoClass 就好像concrete Class(具体类)。

 


这个特性指示编译器在编译Application的时候,使用ApplicationClass 来实现。

 

 

回到上面的最初的问题上:

 

 

 

 

如何让这段代码通过编译:


ITestInterface testInterface = new ITestInterface();

 

通过上面的分析,我们很容易将这个特性来修饰我们的自己的接口:

 

 

namespace CA2005

 


{

 


    [CoClass(typeof(TestClass))]

 


    [Guid("6C8BF7FE-1F6B-437E-BCC8-6D2FF04E66B3")]

 


    public interface ITestInterface

 

 

    {

 


        void DoSomething();

 


    }
 

 

    [Guid("68C7CB18-0DEE-4689-845D-741525281C76")]

 


    public class TestClass : ITestInterface

 

 

    {

 


        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();
 

 

            ITestInterface testInterface = new ITestInterface();

 


            testInterface.DoSomething();

 

 

        }

 


    }

 


}

 

 


编译,结果如下:

 image

接口被标记了CoClassAttribute,而不是ComImportAttribute.

 image

原来想要new 一个接口使用的是编译器对COM的优化和支持。


很明显上面的Application是一个COM对象,所以可以new Application


在ITestApplication中添加ComImportAttribute 特性:

 clip_image002

再次运行,结果如下:

 image

查看下反编译的代码:

 image

之所以我对VS2005 用红色字体,是因为如果你用VS2010 创建的程序,那么你会看到不一样的反编译结果:

 


public static void Main()

补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,