5

私はジェネリック辞書で動作するC#の関数を持っています:

public static string DoStuff<TKey, TValue>(Dictionary<TKey, TValue> dictionary)
{
    // ... stuff happens here
}

オブジェクトをループする関数もあります。これらのオブジェクトの 1 つが Dictionary<> である場合、それをそのジェネリック関数に渡す必要があります。ただし、コンパイル時にキーまたは値の型が何であるかはわかりません。

foreach (object o in Values)
{
    if (/*o is Dictionary<??,??>*/)
    {
        var dictionary = /* cast o to some sort of Dictionary<> */;
        DoStuff(dictionary);
    }
}

どうすればいいですか?

4

2 に答える 2

6

コレクションの型でメソッドをジェネリックにできないと仮定すると、Values動的に使用できます。

foreach (object o in values)
{
    Type t = o.GetType();
    if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Dictionary<,>))
    {
        string str = DoStuff((dynamic)o);
        Console.WriteLine(str);
    }
}

または、リフレクションを使用できます。

foreach (object o in values)
{
    Type t = o.GetType();
    if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Dictionary<,>))
    {
        var typeParams = t.GetGenericArguments();
        var method = typeof(ContainingType).GetMethod("DoStuff").MakeGenericMethod(typeParams);
        string str = (string)method.Invoke(null, new[] { o });
    }
}
于 2012-11-30T23:00:17.217 に答える
4

Valueコレクション内のすべての辞書が同じであることがわかっている場合は、関数もジェネリックにします。

void DealWithIt<T,V>(IEnumerable Values)
{
foreach (object item in Values)
{
    var dictionary = item as Dictionary<T,V>;
    if (dictionary != null)
    {
        DoStuff<T,V>(dictionary);
    }
}

それ以外の場合は、深刻なリフレクション コードに飛び込む前に、非ジェネリックIDictionaryを使用して渡すことを検討してください。DoStuff

于 2012-11-30T22:49:19.353 に答える