在父方法中访问子项的静态属性

说我有以下代码:

class Parent { static string MyField = "ParentField"; public virtual string DoSomething() { return MyField; } } class Child : Parent { static new string MyField = "ChildField"; } 

现在我希望能够做到以下两点:

 Console.WriteLine(Parent.MyField); Console.WriteLine(Child.MyField); 

这些工作按预期工作,但我也想这样做:

 Child c = new Child(); Console.WriteLine(c.DoSomething()); 

由于没有为Child类定义DoSomething(),因此返回的是Parent的MyField,但我想要的是Child的MyField。

所以我的问题是:我有什么方法可以做到这一点?

注意:覆盖Child类中的方法是一个选项,但由于我将从Parentinheritance许多Child类,并且该方法应该在所有这些中执行相同的操作,因此更改此方法中的某些内容会带来很多麻烦。

如果您发现自己需要一种语言不支持的构造,在这种情况下, static virtual成员,这是一种气味,表明您可能有错误的设计。

而不是向我们展示解决方案,向我们展示您尝试使用该解决方案解决的问题。 我的猜测是,有一个完全不同的设计,消除了这种奇怪的需要。

换句话说:你收到的答案不是你想要的答案,因为你问的问题不是你应该问的问题。 我不能想到所提议的设计提供另一种更传统的设计所没有的好处。

你也必须在Child中处理这个问题:

 class Child { static new string MyField = "ChildField"; public override string DoSomething() { return MyField; } } 

话虽这么说,使用单个虚拟属性可能会更简洁,因为您不需要“new”关键字来隐藏Parent的成员字段。

我不明白为什么你认为你需要“静态”和“非静态”环境来调用返回相同内容的不同属性/函数。 如果你这样做:

 class Parent { public virtual string DoSomething() { return "ParentField"; } } class Child { public override string DoSomething() { return "ChildField"; } } 

然后这将按你想要的方式工作:

 Child c = new Child(); Console.WriteLine(c.DoSomething()); 

而不是写这个:

 Console.WriteLine(Parent.MyField); Console.WriteLine(Child.MyField); 

你写这个:

 Console.WriteLine(new Parent().DoSomething()); Console.WriteLine(new Child().DoSomething()); 

这个问题还有一些其他限制使得这个不可接受吗? 例如,由于某种原因,创建这些类的新对象是非常昂贵的吗?

使用静态属性而不是静态变量。 然后,您可以覆盖子类中的属性,而不是创建“新”字段。

是的,覆盖DoSomething:

 class Child { static new string MyField = "ChildField"; public virtual string DoSomething() { return MyField; } } 

在一个响应中,您似乎表明静态字段是常量。 如果是这种情况,那么这应该对你有用。

 class Parent { protected virtual string MyField() { return "ParentField"; } public virtual string DoSomething() { return MyField(); } } class Child : Parent { protected override string MyField() { return "ChildField"; } } 

唯一的方法是重写DoSomething方法,否则就不可能。 Parent方法中的DoSomething实质上转换为:

 public virtual string DoSomething() { return Parent.MyField; } 

当你“ new ”一个属性时,它只适用于那种类型 – 在本例中是Child类。 如果通过’Parent’访问该属性,它将始终返回原始属性。

首先,让我说你真的应该让MyField虚拟并接受你需要生成一个实例来获取它。 但是,另一种“解决”问题的方法是:

 class Parent { public static string MyField = "ParentField"; protected virtual MyLocalField = MyField; public virtual string DoSomething() { return MyLocalField; } } class Child : Parent { public static new string MyField = "ChildField"; protected override MyLocalField = MyField; } 

在任何静态的东西上都没有inheritance魔法,但你可以这样做

 protected virtual string { get { return "your value"; } } 

并使用方法内的属性