2011-01-07 80 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以使名称按值进行比较。