2011-01-07 50 views
1

我打算在一個項目中使用多個名稱索引的字典。我的第一個選擇是使用string鍵,它只是我的Value元素的名稱屬性。字典鍵的類型安全性?

然而,這使得字典鍵相同,即使他們正在訪問不同的類型:

private Dictionary<string, Foo> myFoos; 
private Dictionary<string, Bar> myBars; 

myFoos[bar.Name]; // shouldn't be able to do this! 

我想關鍵是類型互不兼容,使他們無法相互混淆:

private Dictionary<FooName, Foo> myFoos; 
private Dictionary<BarName, Bar> myBars; 

由於每個Value類型創建一個*Name類是矯枉過正,我創建一個Name<T>類:

public struct Name<T> 
{ 
    public string Name; 

    // for convenience, could be explicit instead 
    static implicit operator string(Name<T> name) 
    { 
     return name.Name; 
    } 
} 

這會給我

private Dictionary<Name<Foo>, Foo> myFoos; 
private Dictionary<Name<Bar>, Bar> myBars; 

,然後我可以存儲Name<Foo>實例,而不是字符串。

這看起來有點笨拙,但這是迄今爲止我所見過的最好 - 關於如何更好地實現它的任何建議?
這是錯誤的,或真棒?

回答

4

的第一個問題是:

我想關鍵是類型互不兼容,使他們無法相互混淆:

爲什麼?實際上是否存在混淆的可能性?這並不明顯。請注意,我並不是說你的方法不好;事實上,事實上,這可能是真正的好處。但考慮數組索引器:

int a[]; 
float b[]; 

數組的類型是不兼容的,但都使用整數索引。而是的,這實際上可能會導致問題,當指標混淆 - 可能是你面對你的鑰匙相同類型的問題。

因此,這種情況與您的情況完全相似。也許對不同容器使用相同的密鑰類型並不是那麼糟糕(即使理論上你是對的並且存在混淆的風險)。

+0

當我想存儲Foo擁有的酒吧列表時,問題就出現了。而不是存儲酒吧的第二個副本,我正在存儲Bar.Name - 並且一個Dictionary >開始渾濁水域。 – mskfisher 2011-01-07 14:10:35

5

這將起作用,除了您需要覆蓋EqualsGetHashCode以使名稱按值進行比較。