5

を使用している場合Hashtable、次のようなコードを記述できます。

object item = hashtable[key] ?? default_value;

keyに表示されているかどうかに関係なく機能しますHashtable

私はそれを行うことはできませんDictionary<TKey. TValue>。キーがディクショナリに存在しない場合は、KeyNotFoundException. したがって、次のようなコードを書く必要があります。

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

これはなぜだろうと思います。 Dictionary<TKey, TValue>は単なるラッパーHashtableです。なぜこの制限が追加されたのですか?

編集:

PopCatalin の回答 (以下を参照) の別の観点から、辞書の値が値型の場合、上記のコードは機能しません。を使用している場合Dictionary<int, int>、使用したいコードは次のようになります。

int i = dict[key] ?? default_value;

dict[key]null許容型または参照型ではないため、コンパイルされません。

4

6 に答える 6

8

Dictionary<T>aと aの違いは、HashtableaDictionary<T>が参照型に沿って値型を格納するように特殊化できるジェネリック型であることです。

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

ディクショナリが値の型で特殊化されている場合、それらの値は参照ではなく「値で」返す必要があります。したがって、 null は値の型に対して有効な値Dictionary<T>ではないため、null を返すことはできません。

于 2008-12-30T03:13:01.640 に答える
4

あなたの投稿には1つの誤解があります。Dictionary は Hashtable のラッパーではありません。まったく別の実装です。

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

于 2008-12-30T01:28:07.967 に答える
2

このための拡張機能を作成しました。

public static class DictionaryExtension
{
    public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> items, string key)
    {
        if (items != null && items.ContainsKey(key))
        {
            return items[key];
        }

        return default(TValue);
    }
}
于 2008-12-30T02:41:07.180 に答える
2

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

しかし、理由については、わかりません。

于 2008-12-30T01:28:13.130 に答える
1

Reflector を使用したコードを見ると、Dictionary がキーを見つけようとし、キーが見つからない場合は明示的に例外を発生させることがわかります。

public TValue get_Item(TKey key)
{
    int index = this.FindEntry(key);
    if (index >= 0)
    {
        return this.entries[index].value;
    }
    ThrowHelper.ThrowKeyNotFoundException();
    return default(TValue);
}
于 2008-12-30T01:27:19.310 に答える
0

この制限が、そもそもラッパーを作成する機能上の理由の 1 つであると確信しています。

于 2008-12-30T01:25:51.607 に答える