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

时间:2010-03-10 19:56:41

标签: c# c#-3.0

说我有以下代码:

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类,并且该方法应该在所有这些中执行相同操作,因此更改此方法中的某些内容会带来很麻烦。

9 个答案:

答案 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;
}