0

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

有一次,我有一个非泛型 DbEntityEntry 的实例。实体的类型为 Object。当我使用 GetType() 时,我得到了适当的实体类型。我知道想使用我在存储库中的函数获取相关实体。有没有办法从非通用 DbEntityEntry 中做到这一点。

我试过了:

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

但是我得到了 aRepository<Object>并且对的调用Set<Object>没有按预期返回。

我一直在寻找一种方法来做到这一点,但一无所获。

4

4 回答 4

2

泛型类型的构造函数是为其泛型类型参数生成的特定类的一部分。例如, a 的构造函数与 a 的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>
于 2013-05-02T12:04:15.200 回答
2

看看 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);
}
于 2013-05-02T12:21:28.797 回答
0

你可以做:

T entity = default(T);

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

于 2013-05-02T12:23:36.060 回答
0

如果你可以约束你的泛型类型有一个无参数的构造函数,这个问题可以很好地解决

public Repository(T entity) where T : new()
{
    T foo = new T(); //that's it
}
于 2013-05-02T12:10:06.943 回答