0

当直接从实现类访问接口成员不正确时,我们通常显式实现接口。天气它必须是内部的,否则会导致与 API 设计的冲突,或者当它增加滥用方法的机会时。

在我看来,绝对不鼓励为具有不同逻辑的多个接口单独实现成员,所以这里不是这种情况

编译器不允许将此类实现设为虚拟,因为它没有意义,我认为这是正确的。通常显式实现非常敏感,这就是您尝试隐藏它的原因。

但是我发现了以下覆盖显式实现的方式(它不是完全覆盖,而是它的作弊替代方案)

我发现这令人惊讶且非常失望。我的问题是为什么允许以下代码并且可以完美运行?我希望得到接口已经明确实现的错误。

这只是重现问题的基本示例

static void Main(string[] args)
{
    var b = new Base();
    ((IInterface)b).Write();

    var c = new Child();
    ((IInterface)c).Write();
}
public interface IInterface
{
    void Write();
}
public class Base : IInterface
{
    void IInterface.Write()
    {
        Console.WriteLine("Base");
    }
}
public class Child : Base, IInterface // hack is here. Re Implemented :/
{
    void IInterface.Write()
    {
        Console.WriteLine("Child");
    }
}

Outputs

    Base
    Child
4

2 回答 2

2

为什么允许以下代码并且可以完美运行?

因为规格是这样说的:

显式接口成员实现包含访问修饰符是编译时错误,包含修饰符 abstract、virtual、override 或 static 是编译时错误。

然而在多态性中,俗话说“越派生的类型越好”,再次来自规范:

派生类可以扩展和专门化基类

因此,当您调用该接口成员时,将调用显式实现该接口的最派生类型。

于 2017-09-05T12:24:27.207 回答
0

我建议您考虑从 C# 到本机代码的低级转换:接口继承重新声明,以及它的一个或多个方法覆盖,强制重写 VMT - 虚拟方法表(接口方法在设计上是虚拟的)。

于 2017-09-05T12:18:57.207 回答