我在c#中发现了一个行为,我想知道它是否在规范中(并且可以预期在所有平台和.NET运行时的新版本上工作),或者它是否是恰好可行的未定义行为但可能随时停止编译.
所以,假设我想采用现有的类,如下所示:
public class HtmlTextBox { public string Text {get; set;} } public class HtmlDiv { public string Text {get; set;} }
现在我真的希望他们实现一个通用的IText接口,就像这样:
public interface IText { string Text {get; } }
但我无法直接更改类,因为它们是外部库的一部分.现在有各种方法可以通过继承或装饰器来实现.但我很惊讶地发现,简单地编译并在.NET 4.5(Windows 7 64位)上运行.
public class HtmlTextBox2 : HtmlTextBox, IText {} public class HtmlDiv2 : HtmlDiv, IText {}
而已.这让我可以直接替换HtmlTextBox
并HtmlDiv
使用他们现有的Text
属性作为实现IText
.
我一半期待编译器对我大吼大叫,要求我提供一个明确的重新实现Text
,但是在.NET 4.5中,这只是起作用:
IText h2 = new HtmlTextBox2{Text="Hello World"}; Console.WriteLine(h2.Text); //OUTPUT: hello world
事实上,我在单声道上尝试过相同的功能(无论ideone.com使用的是什么版本),单声道也不会对我大喊大叫
所以我想我很高兴,但在尝试使用严肃的代码之前,我想检查一下我是否误解了这里真正发生的事情,或者我是否不能依赖它来工作.
是的,这是预期的行为.接口方法的实现不需要在实际应用接口的类中完成; 它可以在任何祖先类.
的C#语言规范5.0对此进行了部分13.4.4; 规则的摘录:
特定接口成员的实现
I.M
,其中I
是M
声明成员的接口,通过检查每个类或结构来确定S
,从C
每个连续的基类开始并重复C
,直到找到匹配为止