Ste*_*ger 9 c# generics reflection idictionary
我有一个实现的实例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];
}
Run Code Online (Sandbox Code Playgroud)
我也可以调用TryGetValue,但我认为应该可以调用[]运算符.有谁能够帮我?
Mar*_*ell 22
这将是更好地弄清楚的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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
只是为了完成,即使Marc Gravell的解决方案更好,这就是它如何以我已经开始的方式工作的方式:
object value = dictType.GetMethod("get_Item")
.Invoke(instance, new object[] { key });
Run Code Online (Sandbox Code Playgroud)
这会调用字典的[]运算符.