2013-09-26 19 views
2

我無法闡明這個問題,所以我會用一個例子開始繼承樹的一部分對象的集合:多態性成員字段,當字段這也是

public class BirdCollector 
{ 
    protected Dictionary<string, Bird> nameToBird_; 

    public BirdCollector(Dictionary<string, Bird> nameToBird) 
    { 
     nameToBird_ = nameToBird; 
    } 
} 

public class ExoticBirdCollector 
{ 
    public ExoticBirdCollector(Dictionary<string, Bird> nameToBird) 
    : base(nameToBird) 
    { } 

    public ExoticBird GetExoticBird(string name) 
    { 
     Bird bird; 
     if(nameToBird_.TryGetValue(name, out bird)) 
     { 
      return (ExoticBird)bird; 
     } 
     else 
     { 
      // handle error 
      return null; 
     } 
    } 
} 

詞典我正在進入ExoticBirdCollector包含所有ExoticBird,這擴展了Bird,但我不得不每次都在GetExoticBird()重新投射它們。

是否可以施放這些一次,也許是在構造函數中,這樣每次我從nameToBird_獲得一隻鳥時,它將是一個ExoticBird?編譯器沒有任何方法知道我在地圖中傳遞了所有ExoticBirds,所以除了聲明一個單獨的字典, Dictionary<string, ExoticBird> nameToExoticBird_

我正在考慮現在做的(這似乎是不正確的)在BirdCollector私人的,而不是保護作出nameToBird_,和隱藏它ExoticBirdCollector串和ExoticBird的字典。

我的原始問題已回答,但我有一個相關的後續行動。如果我要求將Dictionary<string, ExoticBird>傳遞給構造函數中接受Dictionary<string, Bird>的新類,那我該如何實現?我懷疑由於對象是在一個容器內部而不能製作下標。我可以創建一個新的Dictionary<string, Bird>並通過Dictionary<string, ExoticBird>循環來填充它,然後傳遞它,但這看起來像一個黑客攻擊。

+0

'ExoticBird'繼承自'Bird'嗎? – EkoostikMartin

+0

是的,我會編輯提及 – tmakino

回答

4

讓你的基類的通用和移動GetBird方法

public class BirdCollector<T> where T : Bird 
{ 
    readonly Dictionary<string, T> nameToBird_; 

    public BirdCollector(Dictionary<string, T> nameToBird) 
    { 
     nameToBird_ = nameToBird; 
    } 

    public T GetBird(string name) 
    { 
     T bird; 

     if (nameToBird_.TryGetValue(name, out bird)) 
     { 
      return bird; 
     } 

     // handle error 
     return null; 
    } 
} 

然後你就可以宣佈它的派生類像這樣

public class ExoticBirdCollector : BirdCollector<ExoticBird> 
{ 
    public ExoticBirdCollector(Dictionary<string, ExoticBird> nameToBird) 
     : base(nameToBird) 
    { 
    } 
} 
+0

謝謝。這解決了我無法將Dictionary 傳遞給構造函數的主要問題。我也喜歡通用的GetBird方法。 – tmakino

1

您可以使用泛型和類型限制:

public class Bird 
{ } 

public class ExoticBird : Bird 
{ } 

public class BirdCollector<T> where T : Bird 
{ 
    protected Dictionary<string, T> nameToBird_; 

    public BirdCollector(Dictionary<string, T> nameToBird) 
    { 
     nameToBird_ = nameToBird; 
    } 
} 

public class ExoticBirdCollector : BirdCollector<ExoticBird> 
{ 
    public ExoticBirdCollector(Dictionary<string, ExoticBird> nameToBird) 
     : base(nameToBird) 
    { } 

    public ExoticBird GetExoticBird(string name) 
    { 
     ExoticBird bird; 
     if (nameToBird_.TryGetValue(name, out bird)) 
     { 
      return bird; 
     } 
     else 
     { 
      // handle error 
      return null; 
     } 
    } 
}