简体   繁体   English

使用Reflection在运行时创建动态泛型

[英]Creating dynamic generics at runtime using Reflection

I'm trying to convert a Dictionary < dynamic , dynamic > to a statically-typed one by examining the types of the keys and values and creating a new Dictionary of the appropriate types using Reflection. 我试图通过检查键和值的类型并使用Reflection创建适当类型的新Dictionary来将Dictionary < dynamicdynamic >转换为静态类型。 If I know the key and value types, I can do the following: 如果我知道键和值类型,我可以执行以下操作:

Type dictType = typeof(Dictionary<,>);

        newDict = Activator.CreateInstance(dictType.MakeGenericType(new Type[] { keyType, valueType }));

However, I may need to create, for example, a Dictionary < MyKeyType , dynamic > if the values are not all of the same type, and I can't figure out how to specify the dynamic type, since 但是,我可能需要创建一个Dictionary < MyKeyTypedynamic >如果值不是所有相同的类型,我无法弄清楚如何指定动态类型,因为

typeof(dynamic)

isn't viable. 是不可行的。

How would I go about doing this, and/or is there a simpler way to accomplish what I'm trying to do? 我将如何做到这一点,和/或是否有更简单的方法来完成我想要做的事情?

The C# compiler emits System.Object as the type for "dynamic". C#编译器将System.Object作为“dynamic”的类型发出。 "dynamic" is a language-specific construct and has no corresponding type in the Common Language Infrastructure. “dynamic”是特定于语言的构造,并且在公共语言基础结构中没有对应的类型。 As such, you won't be able to use reflection to create a "dynamic" nor use "dynamic" as a generic type parameter. 因此,您将无法使用反射创建“动态”,也无法使用“动态”作为泛型类型参数。

A Dictionary<dynamic, dynamic> is really a Dictionary<object, object>. 字典<dynamic,dynamic>实际上是Dictionary <object,object>。 What "dynamic" means to the compiler is simply late-bind any member accesses for the object using reflection (the implementation of which lies in the Microsoft.CSharp assembly in case you're curious). “动态”对编译器来说意味着简单地使用反射来绑定对象的任何成员访问(其实现位于Microsoft.CSharp程序集中,以防您感到好奇)。

On a side note, the compiler will also emit an attribute, DynamicAttribute, on fields, parameters, etc. that are "dynamic"; 另外,编译器还会在“动态”的字段,参数等上发出属性DynamicAttribute; that allows people consuming the assembly's metadata to distinguish between a System.Object and a "dynamic". 允许人们使用程序集的元数据来区分System.Object和“dynamic”。 This is how IntelliSense shows a method's parameter as dynamic from an assembly reference, for example. 这就是IntelliSense如何将方法的参数显示为来自装配参考的动态参数。

Dictionary<MyType, Object>

Activator.CreateInstance(typeof (Dictionary<dynamic, dynamic>));

This actually creates a Dictionary<Object, Object> 这实际上创建了一个Dictionary<Object, Object>

The only use I can see from using dynamic instead of object is during code typing you can use dic["some"].MyDynProperty.... but if you create you object with Activator it will return Object so no use in code typing... 我可以从使用动态而不是对象看到的唯一用途是在代码输入期间你可以使用dic [“some”]。MyDynProperty ....但是如果用Activator创建对象,它将返回Object,因此在代码输入时没有用。 ..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM