【发布时间】:2011-04-11 22:37:59
【问题描述】:
在尝试从 Collection<T> 类重写 ICollection<T>.IsReadOnly 属性的显式接口实现时,我遇到了一些文档,指出不能重写显式接口成员实现,因为它们不能具有诸如 virtual 或 @ 之类的修饰符987654325@。在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 转换为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 中的重写方法!这是为什么呢?
【问题讨论】:
标签: c# interface overriding language-features explicit-implementation