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() // 編譯錯誤。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");
}
// 舊版無泛型 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); // 再次裝箱
類別實作 IDisposable 但不想讓呼叫端直接見到 Dispose(),可顯式實作,僅供 using 區塊隱式呼叫。
| 缺點 | 說明 |
|---|---|
| 僅能透過介面呼叫 | 給第三方庫使用時,IntelliSense 不會顯示,易造成「明明實作了卻叫不到」的困惑。 |
| 實值型別仍會裝箱 | 若透過介面變數呼叫,依然發生裝箱,失去效能優勢。 |
| 無法被繼承覆寫 | 顯式實作預設 sealed,衍生類別無法 override,也無法 base 呼叫。 |
| 情境 | 建議 |
|---|---|
| 一般單一介面實作 | 隱式 |
| 多介面同名衝突 | 顯式 (衝突者) |
| 實值型別實作非泛型介面 | 顯式 + 公開強型別多載 |
| 想隱藏成員 (如 IDisposable) | 顯式 |
| 需要衍生類別覆寫 | 隱式 + virtual |
顯式實作是解決特定問題的利器,非日常預設選項。理解其可見性規則、裝箱行為、繼承限制,才能在正確場合發揮效用。