【问题标题】:Cast object to a Dictionary<TKey, TValue>将对象转换为 Dictionary<TKey, TValue>
【发布时间】:2012-11-30 22:43:52
【问题描述】:

我在 C# 中有一个对通用字典进行操作的函数:

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

我还有一个循环对象的函数。如果其中一个对象是 Dictionary,我需要将它传递给该通用函数。但是,在编译时我不知道 Key 或 Values 的类型是什么:

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

我该怎么做?

【问题讨论】:

  • 你能用 IDictionary 代替吗?
  • 我不需要重写 DoStuff 函数来使用 IDictionary 类型吗?这不是一个真正的选择。

标签: c# generics dictionary


【解决方案1】:

如果你知道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,然后再深入研究反射代码。

【讨论】:

    【解决方案2】:

    假设您不能使您的方法在 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 });
        }
    }
    

    【讨论】:

    • +1。实际上反射代码看起来并没有我想象的那么糟糕。
    猜你喜欢
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多