2011-02-10 3 views
1

ConcurrentDictionary.GetOrAdd():私はConcurrentDictionary有する異なる署名を有するValueFactoryの

private static ConcurrentDictionary<int, string> _cd = new ConcurrentDictionary<int, string>(); 

は保守的であるために、アイテムを取得するために使用される実際のキーが目的であるが、私はなく単にそのハッシュコードを使用キー(潜在的に大きい)物体がキーではないように:工場内のオブジェクトを準備する際

public static string GetTheValue(Foo foo) 
{ 
    int keyCode = foo.GetHashCode(); // GetHashCode is overridden to guarantee uniqueness 

    string theValue = _cd.GetOrAdd(keyCode, FooFactory); 

    return theValue; 
} 

しかし、私がfooオブジェクト内のさまざまなプロパティを必要とする:

private static string FooFactory(Foo foo) 
{ 
    string result = null; 

    object propA = foo.A; 
    object propB = foo.B; 

    // ... here be magic to set result 

    return result; 
} 

GetOrAdd()のvalueFactoryパラメータがFunc<int, string>であるため、Fooオブジェクトを渡すことができないように見えます。そうすることは可能ですか?

+2

それをしないでください。 HashCodeは一意ではありません。大きなオブジェクトを使用する必要があります。それはどんな害もしません。 – SLaks

+0

@SLaks:GetHashCode()の代わりにToString()を使用するとします。 – Bullines

+1

** **ただしないでください。 – SLaks

答えて

2

控えめ的にはは、 への実際のキーはアイテムを取得するために使用することは、オブジェクト ですが、私が代わりに単にそのハッシュコード を使用しますキー(可能であれば ラージ)オブジェクトはキーではありません。

は私があなたが関係していると思うと思いますというフレーズを太字にしました。彼らは本当にそうではありません。そのキーがこれらの大きなオブジェクトであるためにあなたの辞書が大きすぎると想像しているなら、それは間違っていると思います。参照型(C#のclass)の場合、キーはの参照のように辞書に格納されます。また、メソッド間でキーを渡すことに心配している場合は、再び考えてください。オブジェクト自体ではなく、参照のみがコピーされて渡されます。

私はSLaksに同意します:Fooタイプ(または実際に呼び出されているもの)をキーとして使用してください。あなたの人生はずっと簡単になります。

3

大きなオブジェクトをキーとして使用しても問題はありません。

オブジェクトがstructでない限り(構造体であってはならない)、それは決してコピーされません。
後で物事を見ることができるようにするなら、あなたのオブジェクトは明らかに周りを囲んでいるので、メモリが漏れることはありません。

GetHashCode()Equals()の実装が妥当(または継承)されている限り、パフォーマンスに影響はありません。私はここに根本的な誤解があると思い

+0

好奇心の尽くして、あなたはOPがそれが大きいと指定したので "あなたは構造体であってはいけません"と言っていますか?または、カスタム値型を一般的にキーとして使用しないでください。私は前者を推測しています。確かにしたいだけです。 –

+0

@ Dan:正しい。 – SLaks

0

これは別の理由で必要でした。他の誰かが私のようにここに来たら、それはどうやってやることができるのです:

public static string GetTheValue(Foo foo) 
{ 
    int keyCode = ... 

    string theValue = _cd.GetOrAdd(keyCode, (key => FooFactory(foo))); //key is not used in the factory 

    return theValue; 
} 
関連する問題