在给定类型对象的情况下,为什么需要使用反射来实例化泛型?

时间:2011-10-10 23:20:51

标签: c# reflection

我有一个与我的实体对应的Type对象列表,我想使用这些类型来实例化相应的通用绑定器......好吧,让我展示一下:

foreach (Type entitytype in Core.EntityList.Entities)
        {   
Type generictype = typeof(CustomBinders.Binder<>);
Type actualtype = generictype.MakeGenericType(new Type[] { entitytype });
IModelBinder custombinder = (IModelBinder)Activator.CreateInstance(actualtype);
.....................

以上工作原理:随后将创建的每个活页夹添加到mvc应用程序使用的活页夹词典中。但为什么我被迫使用反射呢?我相信这涉及运行时间与编译时间,我不明白。类型列表在编译时存在。

如果有人能提出不同的模式和/或向我解释这些事情,那就太好了。看起来给定了一个类型对象,我应该能够使用new实例化一个对象。关于我想做什么是什么动态?

2 个答案:

答案 0 :(得分:1)

如果你想使用new,你可能会想到这样的事情:

foreach (Type entityType in Core.EntityList.Entities)
{   
    IModelBinder obj = new CustomBinders.Binder<entityType>()
    // Then add it to the dictionary
}

但是,这在C#中是非法的 - 它会给出错误“预期的类型或命名空间名称”。泛型需要在编译时定义的类型参数,以便它可以提供所有编译时检查。因此,您需要使用反射动态地执行此操作。

至于在这种情况下实际做了什么反思:

Type generictype = typeof(CustomBinders.Binder<>);

这会引用“ unbound ”泛型类型(即尚未给出其类型参数)。

Type actualtype = generictype.MakeGenericType(new Type[] { entitytype });

这为您提供了对“构造的”类型的引用 - 即将entitytype作为类型参数的类型(即CustomBinders.Binder<entityType>

IModelBinder custombinder = (IModelBinder)Activator.CreateInstance(actualtype);

这为你构建了对象。

答案 1 :(得分:1)

假设您要构建一个表。你已经知道了前面的尺寸,使用了什么材料,花了多少钱等等,所以你只需要继续创建一个桌子。

var table = new Table();

假设您现在想要扩展它并为他们构建其他人的表格,因此您可以在人们可以为其自定义表格制定计划的地方放置一个框。盒子从一开始就在那里,但是你不知道哪个计划会通过那个盒子,并且可能有任意数量的盒子,所以你必须动态地进行它。

foreach(Type plan in planBox) Activator.CreateInstance(plan);

不同之处在于,Type是您在运行时关于给定对象的一段元数据(计划,可以这么说)。如果您在编译时知道类型,那么您可以直接将它放入代码中,但是您不知道通过Core.EntityList.Entities框会发生什么,因此您必须使用反射来适当地使用该运行时信息。

关键是,如果您正在使用运行时信息,则必须使用运行时功能。如果在编译时已知所有类型,请不要使用Type对象。