程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> new 一個接口?

new 一個接口?

編輯:C#入門知識

如果有人問你,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()

 


{

 


      Application application1 = (Application) Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("00024500-0000-0000-C000-000000000046")));

 


      ITestInterface interface1 = new TestClass();

 


      interface1.DoSomething();

 


      Console.ReadLine();

 


}

 


這裡的Type.GetTypeFromCLSID 中的guid是ApplicationClass的Guid,也就是CoClass中Type的Guid:

 

 

[ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents")]

 


    [Guid("00024500-0000-0000-C000-000000000046")]

 


    [TypeLibType(2)]

 


    [ClassInterface(0)]

 


    public class ApplicationClass : _Application, Application, AppEvents_Event

 

 

{

 


}

 


這點一定要注意。

 作者:LoveJenny
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved