我有一个由通用存储库组成的BL和一些实体类型的一些特定实现(My DAL是一个Entity Framework 5模型)。存储库几乎所有功能都使用System.Data.Entity.DbContext的Set()方法。我有一些表达式,比如获取实体T的兄弟,这些不会对Set(Type entityType)的结果起作用。
有一次我有一个非泛型DbEntityEntry的实例。该实体的类型为Object。当我使用GetType()时,我得到了适当的实体类型。我知道想要在Repository中使用我的函数来获取相关实体。有没有办法从非泛型DbEntityEntry中执行此操作。
我试过了:
public Repository(T entity)
{
\\ Construction here
}
但是我收到了Repository<Object>
,并且对Set<Object>
的调用没有按预期返回任何内容。
我已经找到了一种方法来做到这一点,但是空了。
答案 0 :(得分:2)
泛型类型的构造函数是为其泛型类型参数生成的特定类的一部分。例如,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>
答案 1 :(得分:2)
看看George Mauer在this帖子中发布的这个例子。它需要.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);
}
答案 2 :(得分:0)
如果你可以限制你的泛型类型有一个无参数构造函数,这个问题可以很优雅地解决
public Repository(T entity) where T : new()
{
T foo = new T(); //that's it
}
答案 3 :(得分:0)
你可以这样做:
T entity = default(T);
这适用于T的值类型,以及结构和类。其中T是一个类,但它确实需要一个无参数的构造函数。