举个例子:
public interface IFoo
{
IFoo Bar();
}
public class Foo : IFoo
{
public Foo Bar()
{
//...
}
IFoo IFoo.Bar() { return Bar(); } //Why is this necessary?
}
为什么IFoo Bar()
即使在没有强制Foo
转换的IFoo
情况下转换为必要的隐式实现?
举个例子:
public interface IFoo
{
IFoo Bar();
}
public class Foo : IFoo
{
public Foo Bar()
{
//...
}
IFoo IFoo.Bar() { return Bar(); } //Why is this necessary?
}
为什么IFoo Bar()
即使在没有强制Foo
转换的IFoo
情况下转换为必要的隐式实现?
微软对此主题有详细的描述,但归结为多个接口/类的实现,这些接口/类中具有相同的方法。隐式不再适用于这种情况。
class Test
{
static void Main()
{
SampleClass sc = new SampleClass();
IControl ctrl = (IControl)sc;
ISurface srfc = (ISurface)sc;
// The following lines all call the same method.
sc.Paint();
ctrl.Paint();
srfc.Paint();
}
}
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
Console.WriteLine("Paint method in SampleClass");
}
}
// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass
如果我们采用显式方法,我们最终会得到这个。
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
当实现的类型发生冲突时,这一切都归结为提供唯一性。在您的示例中,Foo
是 IFoo
.
在这种情况下需要它,因为 C# 不支持接口的返回类型协变,所以你的函数
public Foo Bar()
{
//...
}
不满足IFoo
接口,因为Bar
方法的返回类型不同。
由于您还想实现接口,因此您唯一的选择是显式地这样做,因为您已经Bar()
在类上定义了一个方法。
你可以像这样解决它(有点难看,但要注意强类型):
public interface IFoo<T> where T : IFoo<T>
{
T Bar();
}
public class Foo : IFoo<Foo>
{
public Foo Bar()
{
//...
}
}
因为您可能并不总是希望实现接口的方法与具有相同签名的另一个版本的方法的行为方式相同。
您可能还希望一个类为接口实现一个方法,但该方法不能从类本身的实例中访问。
我建议您将隐式实现保留为受保护而不是公开。
public class Foo : IFoo
{
**protected virtual** Foo Bar()
{
//...
}
IFoo IFoo.Bar() { return Bar(); }
}
关于为什么/何时在这个线程中使用显式实现有一个相当广泛的答案:
使用显式实现的一个很好的理由是,当您使用 Foo 类时,您可以轻松地使用依赖注入来获得更松散的耦合。