Csharp/C#教程:C#:通过显式指定接口来覆盖属性分享


C#:通过显式指定接口来覆盖属性

在尝试从Collection类覆盖ICollection.IsReadOnly属性的显式接口实现时,我遇到了一些文档,指出显式接口成员实现无法被覆盖,因为它们不能具有virtualabstract等修饰符。 在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; } } 

那么你期望BA的实例表现得像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所以编译器不会警告BC的成员隐藏A的成员; 实际上,由于显式接口实现, A成员已经被隐藏。

如果您更改了类型A以隐式而不是显式地实现IMyInterface那么编译器会警告BC的成员隐藏而不是覆盖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

(0)
上一篇 2021年12月29日
下一篇 2021年12月29日

精彩推荐