C#中的介面

來源:互聯網
上載者:User
文章目錄
  • 1、公有方法實現介面方法
  • 2、私人方法不能實現介面方法
  • 3、實現專門的介面方法(1)
  • 4、實現專門的介面方法(2)
  • 5、結論

本文中所有圖示純為個人理解(參考了Assembly中中繼資料的儲存方式),與真實情況可能有所出入。 圖中綠色表示公有方法,紅色表示私人方法。

本文將通過以下四個案例來分析C#中的介面究竟是如何工作的。

1、公有方法實現介面方法

儘管C#在定義介面時不用指明介面方法的存取控制方式,但預設介面方法均為public型(這可以從反編譯的IL代碼中看到)。下面是使用Reflector查看的介面IL代碼

.class private interface abstract auto ansi IControl{   .method public hidebysig newslot abstract virtual instance void Paint() cil managed   {   }}

實現介面的類需要實現所有介面方法。通常情況下,介面的實現方法也為public型。如下案例:

using System ;interface IControl {   void Paint();}public class EditBox: IControl {   public void Paint()    {      Console.WriteLine("Pain method is called!");   }}class Test {   static void Main()    {      EditBox editbox = new EditBox();       editbox.Paint();      ((IControl)editbox).Paint();   }}

程式的執行結果為:

Pain method is called!Pain method is called!

介面就好像是關係型資料庫中的一對多表,一個介面對應多個介面方法,每個介面方法又對應虛擬方法表(VMT)中的某個公有或私人方法。上面代碼在記憶體中的鏡像可由描述:

我們可以看到直接對Paint方法的調用以及通過介面對Paint方法的調用。可見通過介面對方法進行調用需要多出一道轉換工作,因此執行效率不如直接調用。

2、私人方法不能實現介面方法

如果想將介面方法直接實現為私人方法是辦不到的。下面的EditBox的代碼中Paint方法沒有特殊說明,預設為private,導致代碼無法執行:

using System ;interface IControl {   void Paint();}public class EditBox: IControl {   void Paint()    {      Console.WriteLine("Pain method is called!");   }   public void ShowPaint()   {      this.Paint();      ((IControl)this).Paint();   }}class Test {   static void Main()    {      EditBox editbox = new EditBox();       editbox.ShowPaint();   }}

程式在編譯時間將顯示如下編譯錯誤:““EditBox”不會實現介面成員“IControl.Paint()”。“EditBox.Paint()”或者是靜態、非公用的,或者有錯誤的傳回型別。”

為什麼會這樣呢?

這是由於介面規範中的方法預設的存取權限是public,而類中的預設存取權限是default,也就是說private,因此導致許可權範圍收縮,兩者許可權並不相同,所以必須將類的許可權調整為public才可以使上面的代碼得以執行。

3、實現專門的介面方法(1)

代碼如下:

using System ;interface IControl {   void Paint();}public class EditBox: IControl {   void Paint()    {      Console.WriteLine("Pain method is called!");   }   void IControl.Paint()    {      Console.WriteLine("IControl.Pain method is called!");   }   public void ShowPaint()   {      this.Paint();      ((IControl)this).Paint();   }}class Test {   static void Main()    {      EditBox editbox = new EditBox();       editbox.ShowPaint();      //editbox.Paint();      ((IControl)editbox).Paint();   }}

EditBox類擁有一私人Paint方法,但這並不是介面方法的實現(上例已經分析過)。EditBox類中還包含了一“void IControl.Paint()”方法, 是該方法複寫了介面的Paint方法,該方法是私人的(通過IL代碼可以看出)。

注意:“void IControl.Paint()”前不能加任何的修飾限定符號,諸如public、private等,這在C#的文法中是不允許的。該方法反編譯得到的IL代碼如下:

.class public auto ansi beforefieldinit EditBox      extends object      implements IControl{      .......      .method private hidebysig newslot virtual final instance void IControl.Paint() cil managed      {            .override IControl::Paint      }}

程式運行時記憶體中的鏡像可簡化表示為:

程式執行結果如下:

Pain method is called!IControl.Pain method is called!IControl.Pain method is called!

我們之所以可以通過((IControl)editbox).Paint()方法訪問到代碼是因為介面方法Paint是公有的。但是我們不能通過editbox.Paint()方法訪問到代碼是因為EditBox的Paint方法是私人的。 在EditBox內部,通過ShowPaint方法可以同時訪問私人的Paint方法與介面IControl.Paint方法。

4、實現專門的介面方法(2)

如果EditBox中的Pait方法為公有並且同時提供了IControl.Paint方法,程式將是如何啟動並執行呢?代碼如下:

using System ;interface IControl {   void Paint();}public class EditBox: IControl {   public void Paint()    {      Console.WriteLine("Pain method is called!");   }   void IControl.Paint()    {      Console.WriteLine("IControl.Pain method is called!");   }}class Test {   static void Main()    {      EditBox editbox = new EditBox();       editbox.Paint();      ((IControl)editbox).Paint();   }}

程式執行結果如下:

Pain method is called!IControl.Pain method is called!

程式執行時記憶體布局如下:

可見,EditBox中公有的Paint方法並不是介面實現方法,真正的介面實現方法是IControl.Paint,這將導致editbox.Paint()方法與((IControl)editbox).Paint()的執行結果並不一樣。

5、結論

介面方法的實現通常是通過類中的公有方法實現的;

在一些特殊情況下(程式碼後置、一個類實現的兩個介面具有相同的介面方法等),需要專門實現某個介面的方法。

轉載:http://www.cnblogs.com/zhenyulu/articles/377705.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.