我有一个如下所示的通用类:
public class Repository<T> {...}
我需要用一个字符串实例化它...
例如:
string _sample = "TypeRepository";
var _rep = new Repository<sample>();
我该如何做到这一点?那是否可能?
谢谢!
我有一个如下所示的通用类:
public class Repository<T> {...}
我需要用一个字符串实例化它...
例如:
string _sample = "TypeRepository";
var _rep = new Repository<sample>();
我该如何做到这一点?那是否可能?
谢谢!
这是我的个人意见:
Type genericType = typeof(Repository<>);
Type[] typeArgs = { Type.GetType("TypeRepository") };
Type repositoryType = genericType.MakeGenericType(typeArgs);
object repository = Activator.CreateInstance(repositoryType);
回答评论中的问题。
MethodInfo genericMethod = repositoryType.GetMethod("GetMeSomething");
MethidInfo closedMethod = genericMethod.MakeGenericMethod(typeof(Something));
closedMethod.Invoke(repository, new[] { "Query String" });
首先使用Type.GetType(stringContainingTheGenericTypeArgument)
获取类型对象。
然后使用typeof(Repository<>).MakeGenericType(theTypeObject)
获取泛型类型。
最后使用Activator.CreateInstance
。
这是一个需要使用C# 4.0中的dynamic
关键字的任务。
这里有一些不错的技巧可以让您得到对象实例,但无论如何,当前版本的C#只知道它有一个object
,并且它本身不能做太多事情,因为当前的C#不支持晚期绑定。您至少需要将其转换为已知类型才能对其进行任何操作。最终,您必须在编译时知道所需的类型,否则就会失败。
现在,如果您可以将存储库类限制为实现某些已知接口的类型,则处于更好的状态。
object _rep = Activator.CreateInstance(typeof(Repository<>).MakeGenericType(Type.GetType(_sample)));
Type repType = typeof(Repository <>).MakeGenericType(Type.GetType("System.String"));
object rep = Assembly.GetAssembly(repType).CreateInstance(repType.FullName);
这将创建一个 Repository<string>
的实例。您可以将 "System.String" 替换为任何自己想要的类型。
这是“有点儿”可能的。有点儿意味着你可以做到,但这有点像黑客。
你有三个选项:
如果你事先知道你的类,请使用 switch 语句。基本上像这样:
switch(str){
case "TypeRepository": return new Repository<TypeRepository>;
}
var factory = new Dictionary<string, Func<object>>();
factory.Add( "TypeRepository", () => new Repository<TypeRepository>() );
var theObject = factory["TypeRepository"]() as Repository<TypeRepository>;
List<>
更改为Repository<>
:public static object MakeList( string typeStr )
{
var nameSpace = "MyTestApplication" + ".";
var objType = Type.GetType(nameSpace + typeStr); // NAMESPACE IS REQUIRED
var listType = typeof(List<>).MakeGenericType(objType);
return Activator.CreateInstance(listType);
}
var listOfThings = MakeList("MyCoolObject") as List<MyCoolObject>;
object
,然后您必须将其强制转换为正确的类型,而不是仅返回强类型值。dynamic
,这将节省您进行强制转换的步骤。泛型适用于类型,而不是实例。您可以在此处阅读更多信息。
听起来您只需要向类中添加一个接受所需类型并初始化值的构造函数:
public class Foo<T>
{
private T = default(T);
public Foo(T initValue)
{
_val = T;
}
}
var _rep = new Repository<string>();