概述:C#中的接口实现可以是隐式或显式的。隐式实现是常见的,但显式实现提供了更多控制权,尤其适用于特定情况,如接口方法不想公开在类上的情况。显式实现的调用需要通过接口访问,这可以在特定需求下提供更好的灵活性和可维护性。
介绍
在 C# 中,可以隐式或显式方式实现接口。在大多数情况下,我们使用的是隐式接口实现,即您有一个具有相同接口签名的方法。
internal interface IMyInterface
{
void SayHello();
}
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
显式接口实现是通过在接口方法前面加上接口名称和句点来定义的。该方法只能通过指定的接口访问。
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
请注意,该方法没有公共访问修饰符,因为它只能通过接口访问。
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
何时必须使用显式接口实现?
在以下情况下,必须使用显式接口实现:
类实现两个具有相同方法签名的接口。
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();
您不想在类类型上公开接口方法。您希望用户将类型强制转换为接口以访问该方法。
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() 方法无法通过对象实例访问。您必须将其转换为接口才能访问它。
当涉及继承时,事情会变得复杂。假设您的基类和子类都必须实现相同的接口(隐式或显式),在不同的场景中调用哪个实现?有很多组合。我们在这里只讨论两种情况。
基类和子类都使用隐式接口实现
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),运行时调用基类 ImplicitImplementation 中的接口实现,因为当基类和子类都隐式实现相同的接口时,子类实现会隐藏基类实现。
对于第三个 (v5),运行时调用子类中的接口实现,因为 v5 实例是从子类构造并强制转换为接口的。
基类和子类都使用显式接口实现
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.
这里的输出更清晰易懂。显式接口实现只能通过接口访问。根据强制转换为接口的真实对象实例,运行时将触发该对象实例的接口实现。
您可以隐式和显式实现接口。运行时将调用正确的实现,具体取决于您是使用接口还是类对象来调用它。第三个输出 (v2_1) 演示了从类对象调用时,运行时将选择隐式接口实现。
该文章在 2024/2/21 12:11:59 编辑过