11

我有一个实现的实例IDictionary<T, K>,我在编译时不知道 T 和 K,并且想从中获取所有元素。由于某种原因,我不想使用IEnumerable它,这将是由IDictionary.

我到目前为止的代码:

// getting types
Type iDictType = instance.GetType().GetInterface("IDictionary`2");
Type keyType = iDictType.GetGenericArguments()[0];
Type valueType = iDictType.GetGenericArguments()[1];

// getting the keys
IEnumerable keys = (IEnumerable)dictType.GetProperty("Keys")
  .GetValue(instance, null);

foreach (object key in keys)
{
  // ==> this does not work: calling the [] operator
  object value = dictType.GetProperty("Item")
    .GetValue(instance, new object[] {key } );


  // getting the value from another instance with TryGet
  MethodInfo tryGetValue = iDictType.GetMethod("TryGetValue");
  object[] arguments = new object[] { key, null };
  bool hasElement = (bool)tryGetValue.Invoke(otherInstance, arguments);
  object anotherValue = arguments[1];
}

我也可以调用 TryGetValue,但我认为应该可以调用 [] 运算符。有谁能够帮我?

4

2 回答 2

23

最好弄清楚TKey/ TValue,并通过 - 切换到常规代码,如下MakeGenericMethod所示:

编辑-otherInstance如果它们属于同一类型,您也可以将其作为参数传入)

static class Program
{
    static void Main()
    {
        object obj = new Dictionary<int, string> {
            { 123, "abc" }, { 456, "def" } };

        foreach (Type iType in obj.GetType().GetInterfaces())
        {
            if (iType.IsGenericType && iType.GetGenericTypeDefinition()
                == typeof(IDictionary<,>))
            {
                typeof(Program).GetMethod("ShowContents")
                    .MakeGenericMethod(iType.GetGenericArguments())
                    .Invoke(null, new object[] { obj });
                break;
            }
        }
    }
    public static void ShowContents<TKey, TValue>(
        IDictionary<TKey, TValue> data)
    {
        foreach (var pair in data)
        {
            Console.WriteLine(pair.Key + " = " + pair.Value);
        }
    }    
}
于 2009-05-12T11:14:52.957 回答
6

只是为了完成,即使 Marc Gravell 的解决方案更好,这也是我已经开始的工作方式:

object value = dictType.GetMethod("get_Item")
  .Invoke(instance, new object[] { key });

这调用了字典的 [] 运算符。

于 2009-05-13T15:13:15.757 回答