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

C# 在父方法中访问子方法的静态属性,c#,c#-3.0,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.Write

假设我有以下代码:

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());
因为DoSomething()不是为子类定义的,所以返回的是父类的MyField,但我想要的是子类的MyField

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


注意:重写子类中的方法是一个选项,但由于我将有许多子类继承自父类,并且该方法在所有子类中都应该执行相同的操作,因此更改此方法中的某些内容会带来很多麻烦。

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

您也必须在子类中处理此问题:

class Child
{
    static new string MyField = "ChildField";

    public override string DoSomething()
    {
         return MyField;
    }
}

也就是说,使用单个虚拟财产可能是一种更简洁的设计,因为您不需要“new”关键字来隐藏父级的成员字段。

是的,覆盖DoSomething:

class Child
{
    static new string MyField = "ChildField";

    public virtual string DoSomething()
    {
        return MyField;
    }

}

任何静态的东西都没有继承魔法,但你可以做到这一点

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

在一个响应中使用方法内部的属性,您似乎表明静态场是恒定的。如果是这样的话,那么这应该适合你

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
”属性时,它仅适用于该类型—在本例中为
子类。如果通过“父级”访问该属性,它将始终返回原始属性

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

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());

在这个问题上是否还有其他一些限制因素使其无法接受?由于某些原因,创建这些类的新对象是否非常昂贵?例如,如果您发现自己需要该语言不支持的构造,在这种情况下,静态虚拟成员是一种气味,表明您可能有错误的设计

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


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

首先,让我说,你真的应该让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;
}

我知道我可以这样做,但我也希望避免重写该方法,因为有多个子类,并且该方法应该在所有子类中都执行相同的操作。很抱歉,我忘了在原来的帖子中提到它。@Francisco:只需创建一个(可能)受保护的虚拟(非静态)属性,返回一个常量,然后返回它即可。然后你只需要重写属性…这比重写方法要好得多。缺点是我必须重写/新建2个“东西”,而不是1个。并且必须在非静态环境中访问属性,在静态环境中访问常量。还有其他想法吗?不能重写静态属性。子属性是否从父属性继承?它似乎是隐含的,但没有显示在代码示例中。是的,很抱歉我错过了。已编辑。在这种情况下,我将无法在静态环境中使用它。但DoSomething不是静态的:)+1我希望自己能看到问题的更完整的轮廓。我的问题非常复杂,我无法深入到更详细的内容,而不会太混乱(即使对我自己来说)。我现在明白我的设计肯定是错误的,我将不得不坐下来思考更好的解决方案。谢谢大家的回答。