概述:C#中的接口實現(xiàn)可以是隱式或顯式的。隱式實現(xiàn)是常見的,但顯式實現(xiàn)提供了更多控制權(quán),尤其適用于特定情況,如接口方法不想公開在類上的情況。顯式實現(xiàn)的調(diào)用需要通過接口訪問,這可以在特定需求下提供更好的靈活性和可維護性。
介紹
在 C# 中,可以隱式或顯式方式實現(xiàn)接口。在大多數(shù)情況下,我們使用的是隱式接口實現(xiàn),即您有一個具有相同接口簽名的方法。
internal interface IMyInterface
{
void SayHello();
}
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
顯式接口實現(xiàn)是通過在接口方法前面加上接口名稱和句點來定義的。該方法只能通過指定的接口訪問。
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
請注意,該方法沒有公共訪問修飾符,因為它只能通過接口訪問。
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
何時必須使用顯式接口實現(xiàn)?
在以下情況下,必須使用顯式接口實現(xiàn):
類實現(xiàn)兩個具有相同方法簽名的接口。
internal interface IControl
{
void Paint();
}
internal interface ICanvas
{
void Paint();
}
internal class MyControl : IControl, ICanvas
{
void IControl.Paint()
{
Console.WriteLine("IControl.Paint()");
}
void ICanvas.Paint()
{
Console.WriteLine("ICanvas.Paint()");
}
}
var control = new MyControl();
((IControl)control).Paint();
((ICanvas)control).Paint();
您不想在類類型上公開接口方法。您希望用戶將類型強制轉(zhuǎn)換為接口以訪問該方法。
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
// The following two lines would cause compile error
// 'ExplicitImplementation' does not contain a definition for 'SayHello'
ExplicitImplementation v1 = new ExplicitImplementation();
v1.SayHello();
// The following lines are OK
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
在上面的代碼中,SayHello() 方法無法通過對象實例訪問。您必須將其轉(zhuǎn)換為接口才能訪問它。
當(dāng)涉及繼承時,事情會變得復(fù)雜。假設(shè)您的基類和子類都必須實現(xiàn)相同的接口(隱式或顯式),在不同的場景中調(diào)用哪個實現(xiàn)?有很多組合。我們在這里只討論兩種情況。
基類和子類都使用隱式接口實現(xiàn)
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
internal class ImplicitImplementationSubClass : ImplicitImplementation, IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementationSubClass says hello.");
}
}
ImplicitImplementation v3 = new ImplicitImplementation();
v3.SayHello();
ImplicitImplementation v4 = new ImplicitImplementationSubClass();
v4.SayHello();
IMyInterface v5 = new ImplicitImplementationSubClass();
v5.SayHello();
// Output
ImplicitImplementation says hello. ImplicitImplementation says hello. ImplicitImplementationSubClass says hello.
這里的輸出有點有趣:第一個是顯而易見的。第二個和第三個值得解釋。
對于第二個 (v4),運行時調(diào)用基類 ImplicitImplementation 中的接口實現(xiàn),因為當(dāng)基類和子類都隱式實現(xiàn)相同的接口時,子類實現(xiàn)會隱藏基類實現(xiàn)。
對于第三個 (v5),運行時調(diào)用子類中的接口實現(xiàn),因為 v5 實例是從子類構(gòu)造并強制轉(zhuǎn)換為接口的。
基類和子類都使用顯式接口實現(xiàn)
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
internal class ExplicitImplementationSubClass : ExplicitImplementation, IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementationSubClass says hello explicitly.");
}
public void SayHello()
{
Console.WriteLine("ExplicitImplementationSubClass says hello implicitly.");
}
}
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
IMyInterface v2 = new ExplicitImplementationSubClass();
v2.SayHello();
ExplicitImplementationSubClass v2_1 = new ExplicitImplementationSubClass();
v2_1.SayHello();
/// Output
ExplicitImplementation says hello. ExplicitImplementationSubClass says hello explicitly. ExplicitImplementationSubClass says hello implicitly.
這里的輸出更清晰易懂。顯式接口實現(xiàn)只能通過接口訪問。根據(jù)強制轉(zhuǎn)換為接口的真實對象實例,運行時將觸發(fā)該對象實例的接口實現(xiàn)。
您可以隱式和顯式實現(xiàn)接口。運行時將調(diào)用正確的實現(xiàn),具體取決于您是使用接口還是類對象來調(diào)用它。第三個輸出 (v2_1) 演示了從類對象調(diào)用時,運行時將選擇隱式接口實現(xiàn)。
該文章在 2024/2/21 12:11:59 編輯過