从类型参数的实例创建泛型类型的实例

本文关键字:实例 泛型类型 创建 类型参数 | 更新日期: 2023-09-27 18:11:53

我有一个由通用存储库和一些实体类型的特定实现组成的BL(我的DAL是实体框架5模型)。存储库使用System.Data.Entity.DbContext的方法Set()来实现它的几乎所有功能。我有一些表达式,比如获得实体T的兄弟姐妹,这些不会对Set(Type entityType)的结果起作用。

现在我有一个非泛型DbEntityEntry的实例。实体的类型是Object。当我使用GetType()时,我得到了适当的实体类型。我知道我想使用我在仓库中的函数获得相关的实体。是否有办法从非泛型的DbEntityEntry中做到这一点?

我试着:

public Repository(T entity)
{
    '' Construction here
}

但是我得到一个Repository<Object>,并且对Set<Object>的调用没有返回任何预期的结果。

我已经搜索了一种方法来做到这一点,但一无所获。

从类型参数的实例创建泛型类型的实例

看看George Mauer在这个帖子里发布的这个例子。需要。net 4.0或更高版本。

dynamic DynamicCast(object entity, Type to)
{
    var openCast = this.GetType().GetMethod("Cast", BindingFlags.Static | BindingFlags.NonPublic);
    var closeCast = openCast.MakeGenericMethod(to);
    return closeCast.Invoke(entity, new[] { entity });
}
static T Cast<T>(object entity) where T : object
{
    return entity as T;
}

您可以使用稍微修改的变体来创建匹配的Repository实例:

public static dynamic CreateRepository(object entiry, Type targetType)
{
    Type BaseType = typeof(Repository<>);   
    Type ConcreteType = BaseType.MakeGenericType(targetType);
    var Instance = Activator.CreateInstance(ConcreteType, entiry);
    return DynamicCast(Instance, ConcreteType);
}

泛型类型的构造函数是为其泛型类型参数生成的特定的类的一部分。例如,List<int>的构造函数是与List<string>不同的构造函数。换句话说,"查找"类型的代码不能存在于泛型类中。

据我所知,这是你的两个选择:

  • 将对象转换为其实际类型(类似工厂的解决方案)
  • 使用反射创建泛型类实例

要使用反射创建实例,可以使用:

Type genericType = typeof(List<>);
Type genericArgument = typeof(int);
Type specificType = genericType.MakeGenericType(genericArgument);
object instance = Activator.CreateInstance(specificType); // this is a List<int>

如果可以将泛型类型约束为具有无参数构造函数,则可以很好地解决此问题

public Repository(T entity) where T : new()
{
    T foo = new T(); //that's it
}

你可以这样做:

T entity = default(T);

这适用于T的值类型,以及结构和类。其中T是一个类,但是它确实需要一个无参数的构造函数。