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

C# 从类型参数的实例创建泛型类型的实例,c#,generics,C#,Generics,我有一个BL,它由一个通用存储库和几个实体类型的特定实现组成(我的DAL是一个实体框架5模型)。存储库几乎所有的功能都使用System.Data.Entity.DbContext的方法Set()。我有一些表达式,比如获取一个实体T的同级,这些表达式对Set(Type entityType)的结果不起作用 我有一个非泛型DbEntityEntry的实例。实体的类型为Object。当我使用GetType()时,我得到了合适的实体类型。我知道我想使用存储库中的函数获取相关实体。是否有一种方法可以从非泛

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

我有一个非泛型DbEntityEntry的实例。实体的类型为Object。当我使用GetType()时,我得到了合适的实体类型。我知道我想使用存储库中的函数获取相关实体。是否有一种方法可以从非泛型DbEntityEntry执行此操作

我试过:

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();