5

以下のような拡張メソッドがあります。

public static T GetValueAs<T, R>(this IDictionary<string, R> dictionary, string fieldName)
    where T : R
{
    R value;
    if (!dictionary.TryGetValue(fieldName, out value))
        return default(T);

    return (T)value;
}

現在、次の方法で使用できます。

    var dictionary = new Dictionary<string, object>();
    //...
    var list = dictionary.GetValueAs<List<int>, object>("A"); // this may throw ClassCastException - this is expected behavior;

これはかなり問題なく動作しますが、2 番目の型パラメーターは非常に厄介です。C# 4.0 で GetValueAs を書き直すことは可能ですか? メソッドがさまざまな種類の文字列キー辞書に適用可能であり、呼び出しコードで 2 番目の型パラメーターを指定する必要がありません。つまり、使用します。

    var list = dictionary.GetValueAs<List<int>>("A");
または少なくとも次のようなもの
    var list = dictionary.GetValueAs<List<int>, ?>("A");
それ以外の
    var list = dictionary.GetValueAs<List<int>, object>("A");

4

4 に答える 4

1

オブジェクトの辞書でのみ使用する限り、キャストを有効にするために T を参照型に制限できます。

public static T GetValueAs<T>(this IDictionary<string, object> dictionary, string fieldName)
  where T : class {
  object value;
  if (!dictionary.TryGetValue(fieldName, out value))
    return default(T);

  return (T)value;
}

しかし、それはおそらくあなたが望むものではありません。C# バージョン 4でも問題は解決しないことに注意してください

于 2010-04-06T12:59:16.467 に答える
0

おそらく、この動作のために独自の辞書クラスを作成できます。

    public class CastableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
        {
            public TOut GetValueAs<TOut>(TKey key) where TOut : TValue
            {
                TValue result;
                if (this.TryGetValue(key, out result))
                {
                    return (TOut)result;
                }
                return default(TOut);
            }
        }



var d = new CastableDictionary<string, object>();

        d.Add("A", 1);

        d.Add("B", new List<int>() { 1, 2, 3});

        var a = d.GetValueAs<int>("A"); // = 1

        var b = d.GetValueAs<List<int>>("B"); //= 1, 2, 3 

おそらくこれもやりたくないでしょう。

于 2010-04-06T14:34:05.100 に答える
0

どうですか

public static void GetValueAs<T, R>(this IDictionary<string, R> dictionary, string fieldName, out T value)
    where T : R
{
    value = default(T);
    dictionary.TryGetValue(fieldName, out value)
}

次に、次のようなことができます

List<int> list;
dictionary.GetValueAs("fieldName", out list);

基本的に、T が何であるかを推測するには、パラメーターに T 型の何かが必要です。

編集

多分より良い方法は

public static T GetValueAs<T, R>(
    this IDictionary<string, R> dictionary, 
    string fieldName, 
    T defaultValue)
    where T : R
{
    R value = default(R);
    return dictionary.TryGetValue(fieldName, out value) ? 
        (T)value : defaultValue;
}

次に、var と chain を使用できます。これにより、デフォルトを制御できます。

var x = dict.GetValueAs("A", new Dictionary<string,int>).GetValueAs("B", default(int));
于 2010-04-06T13:58:49.390 に答える