如何通过使用类型名称来实例化泛型类?

Posted

技术标签:

【中文标题】如何通过使用类型名称来实例化泛型类?【英文标题】:How to instantiate a generic class by using its type name? 【发布时间】:2011-10-11 02:53:34 【问题描述】:

在我的项目(.NET 3.5)中,我得到了许多这样的 DAO:(每个实体一个)

public class ProductDAO : AbstractDAO<Product> 
...

我需要创建一个函数,该函数将接收 DAO 的名称或其实体的名称(您认为最好的名称)并运行 DAO 的“getAll()”函数。就像这段代码只为一个实体做的那样:

ProductDAO dao = new ProductDAO();
dao.getAll();

我是 C# 新手,如何使用反射来做到这一点?

有点像这样:

String entityName = "Product";
AbstractDAO<?> dao = new AbstractDAO<entityName>()
dao.getAll();

编辑

我忘记了一个细节,这是 getAll() 返回的方式:

IList<Product> products = productDao.getAll();

所以我还需要在列表中使用反射。怎么样?

解决方案

Type daoType = typeof(AbstractDAO<>).Assembly.GetType("Entities.ProductDAO");
Object dao = Activator.CreateInstance(daoType);
object list = dao.GetType().GetMethod("getAll").Invoke(dao, null);

【问题讨论】:

【参考方案1】:

如果您使用泛型并且不想为每个实体类型实现特定的 DAO,您可以使用这个:

Type entityType = typeof(Product); // you can look up the type name by string if you like as well, using `Type.GetType()`
Type abstractDAOType = typeof(AbstractDAO<>).MakeGenericType(entityType);
dynamic dao = Activator.CreateInstance(abstractDAOType); 
dao.getAll();

否则,只需使用计算出的 DAO 名称执行 Type.GetType()(假设您遵循特定的名称约定)。

【讨论】:

dao.getAll() 上我得到一个我找不到的缺失参考:`预定义类型'Microsoft.CSharp.RuntimeBinder.Binder'未定义或导入'我应该导入什么? 要使dynamic 工作,需要为.NET 4 编译项目并且需要引用程序集Microsoft.CSharpSystem.Core 这是个问题,解决方案必须针对 .NET 3.5。因此,我将使用Object 并用dao.dao.GetType().GetMethod("getAll").Invoke(dao, null) 调用它,而不是使用dynamic。但在第一行,Type entityType = Type.GetType("Entities.Product"); 返回 null,Entities 被引用。怎么了? Type.GetType 需要一个程序集限定名称。或者,您可以使用Assembly.GetType(在特定程序集中搜索类型)。关于objectdynamic,您可能希望您的AbstractDAO&lt;&gt; 实现一个提供GetAll 方法的简单接口。然后,您可以将实例强制转换到此接口。这比通过反射进行的后期绑定调用更有效,更不容易出错。【参考方案2】:

试试:

Type d1 = typeof(AbstractDAO<>);
Type[] typeArgs = Type.GetType("ProductDAO");
Type constructed = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(constructed);

o.GetType().GetMethod("getAll").Invoke();

【讨论】:

以上是关于如何通过使用类型名称来实例化泛型类?的主要内容,如果未能解决你的问题,请参考以下文章

Java进阶之泛型

JAVA高级--java泛型

简单的java泛型总结

17.scala的泛型类

Spring 如何初始化泛型类实例

Java--泛型