2011-01-07 6 views
1

プロジェクトで複数の名前付きインデックス付き辞書を使用する予定です。私の最初の選択は、Value要素のNameプロパティだけであるstringキーを使用することでした。辞書キーのタイプの安全?

しかし、これは、彼らがさまざまな種類にアクセスしているにもかかわらず、辞書のキーは同じになり:

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

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

私はお互いに混同し、それらを不可能にするために互いに型互換性がないことがキーをしたいと思います。各Valueタイプに*Nameクラスを作成して以来

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

はやり過ぎですが、私はName<T>クラスを作成しました:

0私

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

を与えるだろうし、私はName<Foo>インスタンスの代わりに文字列を格納することができ

public struct Name<T> 
{ 
    public string Name; 

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

これはちょっと扱いにくいようですが、これまでに私がこれまでに思いついたベストです
これは間違っているか、素晴らしいですか?

答えて

4

最初の質問は次のとおりです。

私はお互いに混同し、それらを不可能にするために互いに型互換性がないことがキーをしたいと思います:

なぜ?実際に混乱する可能性はありますか?これは明らかではありません。あなたの考え方が悪いと言っているわけではありません。実際には、実際にはおそらく実際にこのメリットがあります。配列のインデクサを考えてみましょう。

int a[]; 
float b[]; 

配列の型は互換性がありませんが、どちらも整数インデックスを使用します。 yesこれは、インデックスが混乱しているときに実際に問題になることがあります。おそらく、キーで直面しているのと同じ種類の問題でしょう。

このケースはあなたのものとまったく同じです。おそらく、異なる容器に同じキータイプを使用することは、結局のところ悪いことではありません(理論的には正しいですが、混乱の危険があります)。

+0

Fooが所有するバーのリストを保存するときに問題が発生します。バーの2番目のコピーを保存する代わりに、私はBar.Nameを保存しています - 辞書<文字列、リスト>は水を濁すようになります。 – mskfisher

+0

@mskfisher:それは悪いアプローチです。 *バーを名前だけでなく直接保存しますか?これはコピーを作成するのではなく(あなたのFoosとBarsが構造体でない限り、この場合は存在しません)。それらがクラスである場合、それらを格納することはコピーを作成しません。オブジェクトへの参照を格納するだけです。これはオブジェクト指向の基本的な性質であり、ユースケースは非常に一般的で、[aggregation](http://en.wikipedia.org/wiki/Object_composition)という独自の名前を持っています。 –

+0

@Konrad:いいキャッチ、言及すべきもう一つのこと。私はスレッド間で参照渡しではなく値渡しのコピーを渡したいので、この設計では構造体とクラスの間を行き来してきました。私は今クラスを使って、スレッド間で渡す必要のある各タイプのコピーコンストラクタを作成するだけです。 – mskfisher

5

名前を値で比較するには、EqualsGetHashCodeを上書きする必要があることを除いて、これは機能します。