2012-04-19 13 views
31

私は最近ConditionalWeakTable<TKey,TValue>クラスを検索しました。答えはherehereのように弱参照を使用するIDictionaryです。あなたがクラスを見つけることができますConditionalWeakTable <TKey、TValue>をコンパイラ以外の目的に使用する必要がありますか?

... System.Runtime.CompilerServices名前空間に:

クラスを導入して述べたa definitive MSDN articleがあります。これは汎用的な辞書型ではないため、CompilerServicesにあります。コンパイラライターだけが使用することを意図しています。

再び

以降:

...条件弱いテーブルは、汎用のコレクションであることを意図していない...しかし、あなたは、.NET自分自身の言語や必要性を書いている場合オブジェクトにプロパティをアタッチする機能が公開されている場合は、条件付き弱テーブルを確実に調べる必要があります。

はこれに伴い、クラスのMSDNエントリの説明が読み取ります

を動的に管理対象オブジェクトにオブジェクトフィールドを添付するコンパイラを有効にします。

明らかに、それはもともと非常に特殊な目的のために作成されました - DLRを助けるために、System.Runtime.CompilerServices名前空間はこれを具体化しています。しかし、それはCLR内でさえ、それよりもはるかに広い用途が見つかったようです。例えばILSpyConditionalWeakTableの参照を検索すると、MEFクラスCatalogExportProviderと内部WPF DataGridHelperクラスなどで使用されていることがわかります。

ConditionalWeakTableコンパイラの記述と言語ツールの外で、また将来の.NETバージョンで大幅に変更されるオーバーヘッドやインプリメンテーションが発生する危険性があるかどうかは私の質問です。 (または、避けて、代わりにthis oneのようなカスタム実装を使用する必要があります)。

さらにConditionalWeakTableは、キーと値の間のサイクルの問題に対処するためのephemeronsSystem.Runtime.Compiler.Services. DependentHandle経由)の隠されたCLRの実装を利用して、どのようにこれを容易に達成することができない方法についてhereherehereを読んありカスタム方法で。

答えて

22

ConditionalWeakTableを使用しても問題はありません。エフェメロンが必要な場合は、他に選択肢がほとんどありません。

将来の.NETバージョンは問題ではないと思います。コンパイラだけがこのクラスを使用しても、Microsoftは既存のバイナリとの互換性を損なうことなくそれを変更できませんでした。

オーバーヘッドについては、通常の辞書と比較してオーバーヘッドがあることは間違いありません。多くの場合DependentHandleを持つことは、おそらく通常の参照よりも多くの数のWeakReferenceが高価であるのと同じように高価になります(GCはそれらをスキャンしてゼロにする必要があるかどうかを調べる必要があります)。しかし、あなたがたくさん(数百万)のエントリーを持っていなければ、それは問題ではありません。

+0

ありがとうございます、私は答えとしてマークします。私はあなたが正しいと思います - 弱参照を使用する辞書が必要なので、弱参照を使用する他の実装と比較して、ConditionalWeakTableはオーバーヘッドを導入すべきではありません。 – Riko

+0

ConditionalWeakTableの利用可能性について本当に嬉しく思っていましたが、ドキュメントでこれを気付きました: "Object.GetHashCodeをオーバーライドして等価比較を制御できないため、キーのハッシュコードを明示的に設定することはできません。 Object.GetHashCodeメソッドを使用してハッシュコードを計算するため、Object.GetHashCodeオーバーライドは呼び出されません。 - 私の目的には役に立たないようにする。 :( – ctrlplusb

+6

@Sean: 'ConditionalWeakTable'がキーの参照ID以外のものを使うことはできません。なぜなら、コードがキーを供給することができなくなった時を知ることは不可能です。コレクション内のアイテムと一致する必要があります。 – supercat

関連する問題