4

単に辞書で a を.ContainsKey実行する代わりに、使用しなければならないことに本当に腹が立ちます。value==null実際の例:

var dictionary = new Dictionary<string, FooBar>();
var key = "doesnt exist";
var tmp = dictionary[key] ?? new FooBar(x, y);

代わりに、次の選択肢があります。

var key = "doesnt exist";
FooBar tmp = null;
if (dictionary.ContainsKey(key))
{
    tmp = dictionary[key];
} else {
    tmp = new FooBar(x, y);
}

またはこれ:

FooBar tmp = null;
if (!Dictionary.TryGetValue(key, out tmp))
{
    tmp = new FooBar(x, y);
}

私にとって、このコードは非常に冗長です。IDictionary を実装する (またはキーと値の型へのアクセスを許可する) 組み込みのジェネリック クラスはありますが、キーを検索しようとすると例外がスローされず、代わりに null が返されますか?

4

3 に答える 3

8

問題は、値として保存Dictionary<TKey, TValue>できるため、キーが存在しないのか、それとも値があっただけなのかがわからないことです。もう 1 つの問題は、参照型 (または ) である型に対してのみ有効であることです。 nullnullnullTValueNullable<T>

そうは言っても、そうするために自分で拡張メソッドを書くことができます:

public static class DictionaryUtilities
{
    public static TValue SafeGet<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue defaultIfNotFound = default(TValue))
    {
        TValue value;

        return dict.TryGetValue(key, out value) ? value : defaultIfNotFound;
    }
}

このようにして、次のように辞書をクエリできます。

var sample = new Dictionary<int, string> { {1, "One"}, {2, "Two}, {3, "Three"} };

var willBeNull = sample.SafeGet(4);

var willBeHi = sample.SafeGet(4, "HI!");

もちろん、上記のコードは、値型の場合TValueは値型のデフォルトを返します (つまり、値型が の場合、デフォルトで見つからないint場合に返されます)。0

繰り返しますが、2 つのフォームを作成することもできます.1 つは whereTValueに制約されclass、もう 1 つはfor 値型 structを返すことができます...Nullable<T>

于 2012-10-17T21:26:54.207 に答える
2

ジェネリック コレクションnullは常に有効な値であるとは限らず、 を返すジェネリック メソッドを作成することはできませんnull。デフォルト(T)でなければなりません。

として使用しないことが確実な場合は、default(T) を返すユーティリティ メソッドを簡単に作成できます。

于 2012-10-17T21:30:55.817 に答える
0

拡張する場合は、毎回デフォルトを渡す必要があります。
それはあなたが望むものかもしれません。
Dictionary を実装し、ctor にデフォルト値を渡すことができます。

public class DictionaryWithDefault<T1,T2> : Dictionary<T1,T2>
{   
    private T2 t2Default;
    public new T2 this[T1 t1]
    {   // indexer - if the key is not present return the default
        get
        {
            T2 t2t;
            return TryGetValue(t1, out t2t) ? t2t : t2Default;
        }
        set {
            base[t1] = value;
        }
    }
    public DictionaryWithDefault(T2 _t2) { this.t2Default = _t2; }
}

Dictionary で null の値を許可しないようにする場合は、Add をオーバーライドします。

JamesMH からいくつかの構文を借用 +1

このようなものを使用する場所は、複合キーを持つ辞書です。

これが問題になるのは、デフォルト値を変更すると、t2Default 値が変更されることです。
私はそれに取り組んでいます。
T2 が値型の場合、これは機能します。
T2 が参照型の場合は、ディープ コピーを作成する必要があり、手間をかける価値はありません。

于 2012-10-17T22:34:31.520 に答える