如何覆盖而不是隐藏 C# 子类中的成员变量(字段)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8844649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I override, not hide, a member variable (field) in a C# subclass?
提问by Eagle-Eye
I want this to tell me the Name of both ItemA and ItemB. It should tell me "Subitem\nSubitem", but instead it tells me "Item\nSubitem". This is because the "Name" variable defined in the Subitem class is technically a different variable than the "Name" variable defined in the base Item class. I want to change the original variable to a new value. I don't understand why this isn't the easiest thing ever, considering virtual and override work perfectly with methods. I've been completely unable to find out how to actually overridea variable.
我希望这能告诉我 ItemA 和 ItemB 的名称。它应该告诉我“Subitem\nSubitem”,但它告诉我“Item\nSubitem”。这是因为 Subitem 类中定义的“Name”变量在技术上与基本 Item 类中定义的“Name”变量不同。我想将原始变量更改为新值。我不明白为什么这不是最简单的事情,考虑到 virtual 和 override 与方法完美配合。我完全无法找出如何实际覆盖变量。
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";
}
}
采纳答案by dasblinkenlight
You cannot overridevariables in C#, but you can override properties:
您不能在 C# 中覆盖变量,但可以覆盖属性:
public class Item
{
public virtual string Name {get; protected set;}
}
public class Subitem : Item
{
public override string Name {get; protected set;}
}
Another approach would be to change the value in the subclass, like this:
另一种方法是更改子类中的值,如下所示:
public class Item
{
public string Name = "Item";
}
public class Subitem : Item
{
public Subitem()
{
Name = "Subitem";
}
}
回答by Adam Robinson
There is no concept of polymorphism (which is what makes overridedo its thing) with fields (what you call a variables). What you need to use here instead is a property.
override字段(你称之为变量)没有多态性的概念(这就是做它的事情)。你需要在这里使用的是一个属性。
public class Item
{
public virtual string Name
{
get { return "Item"; }
}
}
public class SubItem : Item
{
public override string Name
{
get { return "Subitem"; }
}
}
回答by Jesse Emond
A possible solution would be to use a property and override its getter, like so:
一个可能的解决方案是使用一个属性并覆盖它的getter,如下所示:
public class Item
{
public virtual string Name { get { return "Item"; } }
}
public class Subitem : Item
{
public override string Name { get { return "Subitem"; } }
}
回答by Jon Hanna
What would "overriding a variable" mean?
“覆盖变量”是什么意思?
A variable is a named location in conceptual memory ("conceptual", because it could be a register, though not very likely with fields).
变量是概念内存中的命名位置(“概念”,因为它可能是一个寄存器,尽管不太可能带有字段)。
Overriding a method substitutes one set of operations for another.
覆盖方法会将一组操作替换为另一组操作。
Since a named location in memory isn't a set of operations, how can you substitute it? What are things that expect to use that named location in memory supposed to do?
由于内存中的命名位置不是一组操作,您如何替换它?期望在内存中使用该命名位置的事情是什么?
If you want to change what is stored in the memory, then just do so when the derived class is constructed:
如果要更改内存中存储的内容,则只需在构造派生类时进行:
public class Item
{
public string Name = "Item";
}
public class Subitem : Item
{
public SubItem()
{
Name = "Subitem";
}
}
If you want to override as set of operations, then define a set of operations (a method or property) to override.
如果您想作为一组操作覆盖,则定义一组要覆盖的操作(方法或属性)。
回答by x3ro
This question is relatively old and the author was probably using C# 5.0 or lower. But I had the same question and came across a very neat solution that works with C# 6.0 and higher that I want to share with you:
这个问题相对较旧,作者可能使用的是 C# 5.0 或更低版本。但是我遇到了同样的问题,并遇到了一个非常简洁的解决方案,它适用于 C# 6.0 及更高版本,我想与您分享:
C# 6.0gives the ability to initialize auto-properties. So one can use just that:
C# 6.0提供了初始化自动属性的能力。所以一个人可以使用:
public class Item
{
public virtual string Name { get; set; } = "Item";
}
public class Subitem : Item
{
public override string Name { get; set; } = "Subitem";
}

