接口继承和属性隐藏问题

本文关键字:隐藏 问题 属性 继承 接口 | 更新日期: 2023-09-27 18:21:44

我最近在基类上引入了一个用于单元测试目的的接口,并遇到了一个奇怪的问题。这是最小可重现的方案:

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命令的输出是合乎逻辑的,但我无法接受最后一个命令的输出,它甚至在使用Base类型的临时变量时输出Child。谁能解释一下这里发生了什么?

更新

通过删除接口IChild((child as Base) as IBase).Text突然导致"Base"。这使我得出结论,只要Child实现IBase(直接或通过接口继承(,结果就会"Child"而不是"Base"

当您重构其他类中的方法以接受IBase而不是Base的参数时,这可能会变得非常棘手,因为它突然导致不同的行为。

接口继承和属性隐藏问题

基本上你在这里投射:

(child as Base) Base,您正在使用BaseText字段。很明显。

但在这里:

(child as Base) as IBase你先Child投射到Base,然后再投射到IBase,这意味着你要Child投射到IBase,这意味着将显示ChildText。您不会通过使用 as 来更改基础对象的 。

所以这里的(child as Base) as IBasechild as IBase一样.

编辑:

编辑的问题不会改变这个答案是正确的事实。正如@InBetween所说,它只是改变了解决Text财产实施的方式。所以Child类不再直接实现IBase,所以现在BaseText将用作最佳匹配。基本上它只是使用一流的实现IBase