属性 returns 字符串来自基础 class 而成员 returns 字符串来自继承 class?

Property returns string from base class while member returns string from inherited class?

程序如下:

public class Program
{
    static void Main()
    {
        MyInheritedClass InheritInstance = new MyInheritedClass();
        Console.WriteLine(InheritInstance.name); // the name field
    }
}

public class MyClass
{
    public string name= "I am the Base"; // the name field
    public string Name   // the Name property
    {
        get
        {
            return this.name;
        }
    }
}

public class MyInheritedClass : MyClass
{
    new public string name= "I inherit Base";
}

这按预期工作。输出是:"I inherit Base"

现在,如果我将 Console.WriteLine(InheritInstance.name); // the name field 更改为 Console.WriteLine(InheritInstance.Name); // the name property,它会神奇地输出:"I am Base"

我很困惑为什么会这样?我调用了MyInheritedClassName属性,MyClassName属性是怎么调用的?或者可能 MyClassName 属性 被调用并且它以某种方式神奇地访问了 MyClass?

的名称字段

它调用你的基 class 属性 因为 Name 属性 仅在基 class 中定义。这是继承的默认和最简单的行为。您可以从基础 class 访问属性。

当您需要从 Base class 控制 属性 时,您可以使用 overridenew 结构来为 属性 在 Child class.

Now if I change Console.WriteLine(InheritInstance.name); // the name field to Console.WriteLine(InheritInstance.Name); // the name property, it magically outputs: "I am Base"

发生这种情况是因为 MyClass 不知道派生的 class 中的 new 运算符。据它所知,它只有一个名为 Name 的字符串字段,它在基 class 中声明。当 属性 通过 getter 检索它时,它会转到那里声明的 name

正如 docs 所说:

When used as a declaration modifier, the new keyword explicitly hides a member that is inherited from a base class. When you hide an inherited member, the derived version of the member replaces the base class version

如果您想覆盖该行为,您可以将 name 声明为 virtual:

public class MyClass
{
    public string name = "I am the Base";
    public virtual string Name { get { return this.name; } }
}

public class MyInheritedClass : MyClass
{
    public new string name = "I inherit Base";
    public override string Name { get { return this.name } };
}

请注意,这看起来和感觉上都是多余的。您可以通过声明单个 virtual 属性:

来避免这种情况
public class MyClass
{
    public virtual string Name { get { return "I am base" } }
}

public class MyInheritedClass : MyClass
{
    public override string Name { get { return "I am derived" } };
}