如何覆盖(而非隐藏)C#子类中的成员变量(字段)?

Eag*_*Eye 28 c# variables overriding new-operator

我希望这能告诉我ItemA和ItemB的名称.它应该告诉我"Subitem \nSubitem",但它告诉我"Item \nSubitem".这是因为Subitem类中定义的"Name"变量在技术上是与基础Item类中定义的"Name"变量不同的变量.我想将原始变量更改为新值.我不明白为什么这不是最简单的事情,考虑虚拟和覆盖完美的方法工作.我一直无法找到如何实际覆盖变量.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine(ItemA.Name);
            System.Console.WriteLine(ItemB.Name);
            System.Console.ReadKey();
        }
        static Item ItemA = new Subitem();
        static Subitem ItemB = new Subitem();
    }
    public class Item
    {
        public string Name = "Item";
    }
    public class Subitem : Item
    {
        new public string Name = "Subitem";
    }
}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 39

您不能在C#中覆盖变量,但可以覆盖属性:

public class Item
{
    public virtual string Name {get; protected set;}
}
public class Subitem : Item
{
    public override string Name {get; protected set;}
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是更改​​子类中的值,如下所示:

public class Item
{
    public string Name = "Item";
}
public class Subitem : Item
{
    public Subitem()
    {
        Name = "Subitem";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Eagle-Eye 多态变量会做什么?如果你不能阐明理论,就不要批评实践。 (2认同)
  • @Jon 现在重读我的评论,说起来有点愚蠢。我真正的意思是,我希望我可以在子类中设置变量的默认值,而无需在构造函数中使用它(因为我来自脚本语言,这就是它的完成方式)。我之前表达得不好。然而,“不能阐明理论就不要批评实践”到底是什么意思呢?至于“其他方法看起来很愚蠢和老套”,我指的是我创建一个 get 方法只是为了有一个单独的默认值。(不过,我确实后悔使用了“愚蠢”这个词。) (2认同)

Ada*_*son 8

override用字段(你称之为变量)没有多态性的概念(这就是它的功能).你需要在这里使用的是一个属性.

public class Item
{
    public virtual string Name
    {
        get { return "Item"; }
    }
}

public class SubItem : Item
{
    public override string Name
    {
        get { return "Subitem"; }
    }
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*nna 5

"覆盖变量"是什么意思?

变量是概念内存中的命名位置("概念",因为它可能是一个寄存器,但不太可能是字段).

覆盖方法会将一组操作替换为另一组操作.

由于内存中的命名位置不是一组操作,您如何替换它?什么是期望在内存中使用该命名位置的东西应该做什么?

如果要更改存储在内存中的内容,则只需在构造派生类时执行此操作:

public class Item
{
  public string Name = "Item";
}
public class Subitem : Item
{
  public SubItem()
  {
    Name = "Subitem";
  }
}
Run Code Online (Sandbox Code Playgroud)

如果要覆盖操作集,则定义要覆盖的一组操作(方法或属性).


x3r*_*3ro 5

这个问题相对较旧,作者可能使用的是 C# 5.0 或更低版本。但是我遇到了同样的问题,并遇到了一个非常简洁的解决方案,它适用于 C# 6.0 及更高版本,我想与您分享:

C# 6.0提供了初始化自动属性的能力。所以一个人可以使用:

public class Item
{
    public virtual string Name { get; set; } = "Item";
}

public class Subitem : Item
{
    public override string Name { get; set; } = "Subitem";
}
Run Code Online (Sandbox Code Playgroud)

  • 对我来说最直观的解决方案! (2认同)