c# - 接口(interface)继承和属性隐藏麻烦

标签 c# inheritance interface

我最近为单元测试目的在基类上引入了一个接口(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 并且您正在使用 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

关于c# - 接口(interface)继承和属性隐藏麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33692491/

相关文章:

c# - 在线 Exe 生成器

excel - 如何使用 Excel VBA 中的工具

java - 如何在Java中正确实现MVC模式?

c# - Bouncy CaSTLe X509 Bind to Port Error 指定的登录 session 不存在。它可能已经被终止

c# - 更改 WebFaultException 的内容类型

javascript - Typescript 中的私有(private)继承等价物(仅包括或排除特定的类成员或属性)

c++ - 基类是否可能具有派生类中没有的函数?

php - 仅为一个接口(interface)配置 openvpn 客户端

c# - 无法从字符串创建 StreamReader 类

java - 确认此继承有效