说我有以下代码:
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类中的方法是一个选项,但由于我将从Parent继承许多Child类,并且该方法应该在所有这些中执行相同操作,因此更改此方法中的某些内容会带来很麻烦。
答案 0 :(得分:7)
如果您发现自己需要一种语言不支持的构造,在这种情况下是static virtual
成员,那就是气味,表明您的设计可能有问题。
不要向我们展示解决方案,而是向我们展示您尝试使用该解决方案解决的问题。我的猜测是,有一个完全不同的设计,消除了这种奇怪的需要。
换句话说:你收到的答案不是你想要的答案,因为你问的问题不是你应该问的问题。我认为所提出的设计不会带来另一种更传统的设计所带来的好处。
答案 1 :(得分:1)
你也必须在Child中处理这个问题:
class Child
{
static new string MyField = "ChildField";
public override string DoSomething()
{
return MyField;
}
}
话虽这么说,使用单个虚拟属性可能会更简洁,因为您不需要“new”关键字来隐藏Parent的成员字段。
答案 2 :(得分:1)
我不明白为什么你认为你需要“静态”和“非静态”环境来调用返回相同内容的不同属性/函数。如果你这样做:
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());
这个问题还有一些其他限制使得这个不可接受吗?由于某些原因,创建这些类的新对象是非常昂贵的,例如?
答案 3 :(得分:0)
使用静态属性而不是静态变量。然后,您可以覆盖子类中的属性,而不是创建“新”字段。
答案 4 :(得分:0)
是的,覆盖DoSomething:
class Child
{
static new string MyField = "ChildField";
public virtual string DoSomething()
{
return MyField;
}
}
答案 5 :(得分:0)
在任何静态的东西上都没有继承魔法但你可以用这个
protected virtual string { get { return "your value"; } }
并使用方法中的属性
答案 6 :(得分:0)
在一个响应中,您似乎表明静态字段是常量。如果是这种情况,那么这应该适合你。
class Parent
{
protected virtual string MyField() { return "ParentField"; }
public virtual string DoSomething()
{
return MyField();
}
}
class Child : Parent
{
protected override string MyField() { return "ChildField"; }
}
答案 7 :(得分:0)
唯一的方法是覆盖DoSomething
方法,否则就不可能。 DoSomething
方法中的Parent
基本上转换为:
public virtual string DoSomething()
{
return Parent.MyField;
}
当您“new
”属性时,它仅适用于该类型 - 在本例中为Child
类。如果通过'Parent'访问该属性,它将始终返回原始属性。
答案 8 :(得分:0)
首先,让我说你真的应该让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;
}