【问题标题】: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);

【问题讨论】:

    标签: c# reflection .net-3.5


    【解决方案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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      相关资源
      最近更新 更多