我最近为单元测试目的在基类上引入了一个接口(interface),但遇到了一个奇怪的问题。这是最小的可重现场景:
interface IBase
{
string Text { get; }
}
interface IChild : IBase
{
}
class Base : IBase
{
public string Text { get { return "Base"; }}
}
class Child : Base, IChild
{
public new string Text { get { return "Child"; }}
}
static void Main(string[] args)
{
var child = new Child();
Console.WriteLine(child.Text); // Outputs "Child"
Console.WriteLine((child as Base).Text); // Outputs "Base"
Console.WriteLine(((child as Base) as IBase).Text); // Outputs "Child"
}
前两个Console.WriteLine
命令的输出是合乎逻辑的,但我无法接受最后一个的输出,它甚至在使用临时文件时输出Child
Base
类型的变量。谁能解释这里发生了什么?
更新
通过删除接口(interface) IChild
,((child as Base) as IBase).Text
突然导致 “Base”
。这让我得出结论,只要 Child
实现了 IBase
(直接或通过接口(interface)继承),结果将是 "Child"
而不是 “基地”
。
当您重构其他类中的方法以采用 IBase
而不是 Base
的参数时,这会变得非常棘手,因为它会突然导致不同的行为。
最佳答案
基本上你在这里转换:
(child as Base)
到 Base
并且您正在使用 Base
的 Text
字段。很明显。
但是在这里:
(child as Base) as IBase
你正在将 Child
转换为 Base
然后转换为 IBase
这意味着您正在将 Child
转换为 IBase
,这意味着将显示 Child
的 Text
。您不是通过使用 as
来更改底层对象的。
所以这里的(child as Base) as IBase
和child as IBase
是一样的。
编辑:
编辑后的问题不会改变这个答案是正确的事实。正如@InBetween 所说,它只是改变了 Text
属性的实现方式。所以 Child
类不再直接实现 IBase
,所以现在 Base
的 Text
将用作最佳匹配。基本上它只是使用一流的实现 IBase
关于c# - 接口(interface)继承和属性隐藏麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33692491/