在尝试ICollection<T>.IsReadOnly
从类中覆盖属性的显式接口实现时Collection<T>
,我遇到了一些文档,指出显式接口成员实现不能被覆盖,因为它们不能具有诸如virtual
or之类的修饰符abstract
。在MSDN上,他们甚至通过创建由显式接口成员实现调用的另一个抽象或虚拟成员来指定如何使显式接口成员实现可用于继承。到目前为止没有问题。
但后来我想知道:为什么在 C# 中可以通过显式指定接口来覆盖任何显式实现的接口成员?
例如,假设我有一个像这样的简单接口,带有一个属性和方法:
public interface IMyInterface
{
bool AlwaysFalse { get; }
bool IsTrue(bool value);
}
以及一个显式实现接口的类A
,并且有一个Test()
调用它自己的接口成员实现的方法。
public class A : IMyInterface
{
bool IMyInterface.AlwaysFalse
{ get { return false; } }
bool IMyInterface.IsTrue(bool value)
{ return value; }
public bool Test()
{ return ((IMyInterface)this).AlwaysFalse; }
}
如您所见,这四个成员都不是虚拟的或抽象的,所以当我这样定义一个类时B
:
public class B : A
{
public bool AlwaysFalse
{ get { return true; } }
public bool IsTrue(bool value)
{ return !value; }
}
然后你会期望B
cast的实例A
表现得像A
. 它确实:
A a = new A();
Console.WriteLine(((IMyInterface)a).AlwaysFalse); // False
Console.WriteLine(((IMyInterface)a).IsTrue(false)); // False
Console.WriteLine(a.Test()); // False
A b = new B();
Console.WriteLine(((IMyInterface)b).AlwaysFalse); // False
Console.WriteLine(((IMyInterface)b).IsTrue(false)); // False
Console.WriteLine(b.Test()); // False
现在来了。创建一个类,它是类声明中除了一件事C
的精确副本:B
public class C : A, IMyInterface
{ /* ... same as B ... */ }
现在 的实例C
,当转换为 时A
,其行为不像A
,而是像C
:
A c = new C();
Console.WriteLine(((IMyInterface)c).AlwaysFalse); // True
Console.WriteLine(((IMyInterface)c).IsTrue(false)); // True
Console.WriteLine(c.Test()); // True
甚至该Test()
方法现在也调用了C
! 为什么是这样?