2010-03-10 42 views
3

说我有下面的代码:访问一个孩子的静态属性在父类的方法

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。

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

注意:覆盖Child类中的方法是一个选项,但由于我将有大量从Parent继承的Child类,并且方法应该在所有方法中都做同样的事情,所以更改此方法中的某些内容带来很多麻烦。

+0

孩子是否从父母继承?它似乎暗示但未在代码示例中显示。 – 2010-03-10 20:19:00

+0

是的,对不起,我错过了。编辑。 – 2010-03-10 20:33:32

回答

7

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

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

换句话说:你收到的答案不是你想要的,因为你问的问题并不是你应该问的问题。我可以想象,所提出的设计不会带来另一种更常规设计所不具备的优势。

+0

+1我希望自己能够看到更完整的问题概要。 – 2010-03-10 21:32:59

+0

我的问题非常复杂,我无法进入更多的细节而不会让人感到困惑(即使是我自己)。我现在明白我的设计绝对是错误的,我将不得不坐下来思考一个更好的解决方案。感谢大家的答案。 – 2010-03-11 00:18:23

+0

祝你好运:-) – 2010-03-11 00:56:15

0

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

+0

您无法覆盖静态属性。 – 2010-03-10 20:12:14

1

你有孩子处理这个问题,太:

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

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

话虽这么说,使用单一的虚拟财产可能会是一个更清洁的设计,因为你不会需要“新”的关键字隐藏父母的成员字段。

+0

我明白我可以做到这一点,但我也想避免重写该方法,因为有多个Child类,并且该方法应该在所有这些类中执行相同的操作。对不起,我忘了在原文中提到它。 – 2010-03-10 20:08:15

+0

@Francisco:只需创建一个(可能)保护的虚拟(非静态)属性,返回一个常量,然后返回该属性。那么你只需要重写属性... – 2010-03-10 20:09:20

+0

这比重写方法好得多。 缺点是我必须重写/新的2个“事物”而不是1个。并且必须在非静态环境中访问属性,并在静态环境中访问常量。 有没有其他想法? – 2010-03-10 20:19:31

0

是,覆盖的DoSomething:

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

    public virtual string DoSomething() 
    { 
     return MyField; 
    } 

} 
0

有任何东西没有继承魔法静态的,而是你能做到这一点

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

,并用你的方法

+0

在这种情况下,我将无法在静态环境中使用它。 – 2010-03-10 20:34:46

+0

但DoSomething不是静态的:) – 2010-03-11 12:16:25

0

在一个响应你内心的财产似乎表明静态字段是恒定的。如果是这样,那么这应该适合你。

class Parent 
{ 
    protected virtual string MyField() { return "ParentField"; } 

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

class Child : Parent 
{ 
    protected override string MyField() { return "ChildField"; } 
} 
0

唯一的方法是覆盖DoSomething方法,否则它是不可能的。该DoSomethingParent方法主要转化为:

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

当你“new”的属性,它仅适用于该类型 - 在这种情况下Child类。如果通过“父”访问该属性,它将始终返回原始属性。

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

是否有其他约束这个问题让人无法接受?例如,是否因某种原因创建这些类的新对象非常昂贵?

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; 
} 
相关问题