首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 介面實作詳解:隱式 vs 顯式實作的差異、適用場景與陷阱

     編輯:關於C語言

基本語法對比

隱式實作 (預設、最常用)

interface ILog { void Log(); }

public class FileLogger : ILog
{
    public void Log() => Console.WriteLine("寫入檔案");
}
  • 方法必須 public。
  • 可透過具體型別 直接呼叫:new FileLogger().Log()。
  • 可標記 virtual 供衍生類別覆寫。

顯式實作

public class EventLogger : ILog
{
    void ILog.Log() => Console.WriteLine("寫入事件檢視器"); // 無 public、無 virtual
}
  • 方法前綴 介面名稱.,不允許存取修飾詞 (預設 private)。
  • 僅能透過 介面型別變數 呼叫:ILog log = new EventLogger(); log.Log();
  • 具體型別變數 不可見:new EventLogger().Log() // 編譯錯誤。

三大適用場景

1. 多介面同名方法衝突

interface ISendable { void Send(); }
interface ILog { void Send(); } // 同名

public class MailLogger : ILog, ISendable
{
    void ILog.Send() => Console.WriteLine("Log Send");
    void ISendable.Send() => Console.WriteLine("Mail Send");
}

2. 實值型別避免裝箱 + 編譯期型別安全

// 舊版無泛型 IComparable
struct Point : IComparable
{
    public int X;
    // 顯式實作介面方法 (參數 object)
    int IComparable.CompareTo(object obj) => CompareTo((Point)obj);
    // 供內部強型別呼叫
    public int CompareTo(Point other) => X - other.X;
}

// 使用
var p1 = new Point { X = 1 };
var p2 = new Point { X = 2 };
Console.WriteLine(p1.CompareTo(p2)); // 無裝箱、型別安全

// 若用介面變數則仍會裝箱
IComparable c = p1; // 裝箱
c.CompareTo(p2);    // 再次裝箱

3. 隱藏成員、避免介面汙染公開 API

類別實作 IDisposable 但不想讓呼叫端直接見到 Dispose(),可顯式實作,僅供 using 區塊隱式呼叫。

三大缺點與注意事項

缺點說明
僅能透過介面呼叫給第三方庫使用時,IntelliSense 不會顯示,易造成「明明實作了卻叫不到」的困惑。
實值型別仍會裝箱若透過介面變數呼叫,依然發生裝箱,失去效能優勢。
無法被繼承覆寫顯式實作預設 sealed,衍生類別無法 override,也無法 base 呼叫。

決策速查

情境建議
一般單一介面實作隱式
多介面同名衝突顯式 (衝突者)
實值型別實作非泛型介面顯式 + 公開強型別多載
想隱藏成員 (如 IDisposable)顯式
需要衍生類別覆寫隱式 + virtual

結語

顯式實作是解決特定問題的利器,非日常預設選項。理解其可見性規則、裝箱行為、繼承限制,才能在正確場合發揮效用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved