C#:通过显式指定接口来覆盖属性
在尝试从Collection
类覆盖ICollection.IsReadOnly
属性的显式接口实现时,我遇到了一些文档,指出显式接口成员实现无法被覆盖,因为它们不能具有virtual
或abstract
等修饰符。 在MSDN上,他们甚至可以通过创建另一个由显式接口成员实现调用的抽象或虚拟成员来指定如何使显式接口成员实现可用于inheritance。 到目前为止没问题。
但后来我想知道: 为什么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 ... */ }
现在,当转换为A
时, C
的实例不像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
的重写方法! 为什么是这样?
这与显式接口实现无关 ; 它只是inheritance和接口映射的一般规则的结果:如果类型A
提供了IMyInterface的隐式而非显式的实现,您会看到完全相同的结果。
因为类型A
显式地实现了IMyInterface
所以编译器不会警告B
和C
的成员隐藏A
的成员; 实际上,由于显式接口实现, A
成员已经被隐藏。
如果您更改了类型A
以隐式而不是显式地实现IMyInterface
那么编译器会警告B
和C
的成员隐藏而不是覆盖A
的成员,并且理想情况下在B
声明这些成员时应使用new
修饰符C
以下是语言规范中的一些相关位。 ( ECMA-334规范中的第20.4.2和20.4.4节; Microsoft C#4规范中的第13.4.4和13.4.6节)
20.4.2接口映射
特定接口成员
IM
,其中I
是声明成员M
的接口,通过检查每个类或结构S
来确定,从C
开始并重复每个连续的C
类基类,直到找到匹配为止。20.4.4接口重新实现
允许inheritance接口实现的类通过将其包含在基类列表中来重新实现接口。 接口的重新实现遵循与接口的初始实现完全相同的接口映射规则。 因此,inheritance的接口映射对于为接口的重新实现而建立的接口映射没有任何影响。
上述就是C#学习教程:C#:通过显式指定接口来覆盖属性分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1011906.html