2013年12月5日木曜日

Dictionaryのレビューポイント

Dictionary<TKey, TValue>

Dictionaryは非常に便利なのですが、理解してから使わなければ、
よく例外を発生させてしまいます。
Dictionaryまわりは不具合率が極めて高いです。
レビュー時のポイントをまとめてみましょう。


・<最重要>Dicitionary.AddでKeyは絶対に重複しないか?
キーが重複すると例外が発生します。
絶対に重複しないことを確かめましょう。
既に存在している場合に上書きを期待する場合は、
Addの使用はやめて
dictionary[key] = value;
とインデックス指定での代入を行いましょう。
インデックス指定での代入であれば
キーが既に登録されていても例外が発生することはありません。


・Keyが絶対に存在しているか?
dictionary[key]を代入用途以外で使用する場合、
keyが存在していなければ例外が発生します。


・ContainsKey(key) -> dictionary[key]?

if (dictionary.ContainsKey(key))
 ... = dictionary[key];

かと言って上記のようなコードはあまり書くべきではないので、
この場合、TryGetValueメソッドを使用しましょう。
マルチスレッドであれば、ContainsKeyしたタイミングと
要素アクセスにいくタイミングが違えば、
チェックに意味がない場合が発生します。


・Dicitionary.AddでKeyは絶対にnullにはならないか?
nullのvalueは許容されても、nullのkeyは許容されずに例外発生です。


・Value使ってる?
たまにContainsKeyで、高速に要素が含んでいるかどうかを確かめるためだけに、
Dictionaryを使用してしまう人がいます。
Value使わないならHashSet使いましょう。


・Comparer利用の方が綺麗にならないか?
TKeyがstringの場合で、ToUpperなどで大文字・小文字の違いを吸収しているような場合、

new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)

とすることで利用時の負担を減らすことができます。


・foreach(var key in dictionary.Key)
KeyValuePairでforeachをまわすほうが綺麗な場合があります。
foreach(var keyValue in dictionary)


・dictionary.Keys.Contains
遅いです。dictionaryの意味がないです。
ContainsKeyを使って下さい。


・1つのKeyに対して二つ以上の要素を格納している場合
Value部分をListなどにするのもありだと思いますが、
ToLookupで作成できるLookupの利用可否を検討して下さい。
まぁ少し使用方法に癖がありますが、はまればコードが綺麗になります。

0 件のコメント:

コメントを投稿