2010-03-10 46 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; 
} 
相關問題