C# 从类型参数的实例创建泛型类型的实例
我有一个BL,它由一个通用存储库和几个实体类型的特定实现组成(我的DAL是一个实体框架5模型)。存储库几乎所有的功能都使用System.Data.Entity.DbContext的方法Set()。我有一些表达式,比如获取一个实体T的同级,这些表达式对Set(Type entityType)的结果不起作用 我有一个非泛型DbEntityEntry的实例。实体的类型为Object。当我使用GetType()时,我得到了合适的实体类型。我知道我想使用存储库中的函数获取相关实体。是否有一种方法可以从非泛型DbEntityEntry执行此操作 我试过:C# 从类型参数的实例创建泛型类型的实例,c#,generics,C#,Generics,我有一个BL,它由一个通用存储库和几个实体类型的特定实现组成(我的DAL是一个实体框架5模型)。存储库几乎所有的功能都使用System.Data.Entity.DbContext的方法Set()。我有一些表达式,比如获取一个实体T的同级,这些表达式对Set(Type entityType)的结果不起作用 我有一个非泛型DbEntityEntry的实例。实体的类型为Object。当我使用GetType()时,我得到了合适的实体类型。我知道我想使用存储库中的函数获取相关实体。是否有一种方法可以从非泛
public Repository(T entity)
{
\\ Construction here
}
但是我得到了一个存储库
,调用Set
不会像预期的那样返回任何结果
我已经搜索了一种方法来实现这一点,但结果是空的。泛型类型的构造函数是为其泛型类型参数生成的特定类的一部分。例如,
列表
的构造函数与列表
的构造函数不同。换句话说,“查找”类型的代码不能存在于泛型类中
据我所知,这是你的两个选择:
- 将对象转换为其实际类型(类似工厂的解决方案)
- 使用反射创建泛型类实例
Type genericType = typeof(List<>);
Type genericArgument = typeof(int);
Type specificType = genericType.MakeGenericType(genericArgument);
object instance = Activator.CreateInstance(specificType); // this is a List<int>
Type genericType=typeof(列表);
类型genericalargument=typeof(int);
类型specificType=genericType.MakeGenericType(genericArgument);
对象实例=Activator.CreateInstance(specificType);//这是一份清单
泛型类型的构造函数是为其泛型类型参数生成的特定类的一部分。例如,列表
的构造函数与列表
的构造函数不同。换句话说,“查找”类型的代码不能存在于泛型类中
据我所知,这是你的两个选择:
- 将对象转换为其实际类型(类似工厂的解决方案)
- 使用反射创建泛型类实例
Type genericType = typeof(List<>);
Type genericArgument = typeof(int);
Type specificType = genericType.MakeGenericType(genericArgument);
object instance = Activator.CreateInstance(specificType); // this is a List<int>
Type genericType=typeof(列表);
类型genericalargument=typeof(int);
类型specificType=genericType.MakeGenericType(genericArgument);
对象实例=Activator.CreateInstance(specificType);//这是一份清单
如果您可以约束泛型类型使用无参数构造函数,那么这个问题可以非常优雅地解决
public Repository(T entity) where T : new()
{
T foo = new T(); //that's it
}
如果您可以将泛型类型约束为具有无参数构造函数,那么这个问题可以非常优雅地解决
public Repository(T entity) where T : new()
{
T foo = new T(); //that's it
}
看看George Mauer在thread中发布的这个示例。它需要.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;
}
看看George Mauer在thread中发布的这个示例。它需要.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;
}
你可以做:
T entity = default(T);
这既适用于T的值类型,也适用于结构和类。其中T是一个类,但它确实需要一个无参数构造函数。您可以:
T entity = default(T);
这既适用于T的值类型,也适用于结构和类。其中T是一个类,但它确实需要一个无参数构造函数。添加了一个“CreateRepository”的示例实现,我真的看不出
DynamicCast
方法的意义。为什么不将上面CreateRepository
方法的最后一行代码更改为简单的返回实例代码>?因为Activator.CreateInstance有一个返回类型对象
。通过使用DynamicCast,您可以得到正确的类型。我建议进行以下简化:public static object CreateRepository(object entity){var typeDef=typeof(Repository);var constrType=typeDef.MakeGenericType(entity.GetType());var instance=Activator.CreateInstance(constrType,entity);return instance;}
(对您的最新评论):但是如果需要,您可以使用从任何类型到类型的隐式转换dynamic
,如dynamic retVal=new object()
?添加了一个“CreateRepository”的示例实现,我真的看不出DynamicCast
方法的含义。为什么不将上面CreateRepository
方法的最后一行代码更改为返回实例;
?因为Activator.CreateInstance使用DynamicCast有一个返回类型对象您得到了正确的类型。我建议进行以下简化:publicstaticobjectcreaterepository(objectentity){var-typeDef=typeof(Repository);var-constrype=typeDef.MakeGenericType(entity.GetType());var-instance=Activator.CreateInstance(constrype,entity);return-instance;}
(根据您的最新评论):但是如果需要,您可以使用从任何类型到类型的隐式转换dynamic
,如dynamic retVal=new object();
?