5


0

Hashtableのように辞書が存在しないキーにアクセスしないのはなぜですか?

私が `Hashtable`を使っているなら、私はこのようなコードを書くことができます:

object item = hashtable[key] ?? default_value;

それは Hashtable`に key`が現れるかどうかに関係なく働きます。

私はそれを `Dictionary`ではできません。 キーが辞書に存在しない場合、それは `KeyNotFoundException`を投げます。 だから私はこのようなコードを書く必要があります:

MyClass item;
if (!(dict.TryGetValue(key, out item))
{
   item = default_value;
}

これがなぜなのかと思います。 Dictionary`は Hashtable`のラッパーです。 なぜこの制限が追加されたのですか?

編集:

PopCatalinの答えに対する別の見方(下記参照)については、上で書いたコードは辞書の値が値型のものであるとうまくいきません。 私が `Dictionary`を使っているなら、私が使うべきコードは次のようになります。

int i = dict[key] ?? default_value;

そしてそれはコンパイルされません、なぜなら `dict [key]`はnull許容型でも参照型でもないからです。

6 Answer


8


Dictionary`と Hashtable`の違いは `Dictionary`は参照型に沿って値型を格納するのに特化できる一般的な型であるということです。

ハッシュテーブルは参照型(参照渡しされる Object)とボックス化された(参照渡しされる)値型のみを格納できます。

ディクショナリが値型に特化している場合、それらは参照ではなく「値によって」それらの値を返さなければなりません。したがって、nullは値型に対して*有効な値*ではないので、 `Dictionary`はnullを返すことができません。


4


あなたの投稿には1つの誤解があります。 辞書はHashtableのラッパーではありません。 これはまったく異なる実装です。

この変更が行われた理由は、主に1つの主張によって正当化されます。Nullはハッシュテーブルの有効な値です。 この変更がないと、存在しないキーと[]アクセス方法を使用してnull値を持つ値キーを区別することはできません。 辞書はこれを片付ける。


2


このための拡張機能を書きました。

public static class DictionaryExtension {public static TValue GetValueOrDefault(このDictionary項目、文字列のキー){if(items!= null

デフォルトを返します(TValue)。 }}


1


Reflectorを使用してコードを見ると、Dictionaryがキーを見つけようとし、キーが見つからないと_explicitly_が例外を発生させます。

public TValue get_Item(TKey key){int index = this.FindEntry(key); if(index> = 0){return this.entries [index] .value; ThrowHelper.ThrowKeyNotFoundException();デフォルトを返します(TValue)。 }


1


Dictionary.ContainsKeyは、おそらくTryGetValueよりも優れています。

しかし、その理由としては、わかりません。


0


私はこの制限が最初にラッパーを作成するための機能的理由の1つであると確信しています。