Jef*_*eff 128 c# generics reflection activator
在C#中我有以下对象:
public class Item
{ }
public class Task<T>
{ }
public class TaskA<T> : Task<T>
{ }
public class TaskB<T> : Task<T>
{ }
Run Code Online (Sandbox Code Playgroud)
我想使用C#reflection(Activator.CreateInstance)动态创建TaskA或TaskB .但是我不知道手头的类型,所以我需要动态创建基于字符串的TaskA,如"namespace.TaskA"或"namespace.TaskAB".
JP *_*oto 237
var d1 = typeof(Task<>);
Type[] typeArgs = { typeof(Item) };
var makeme = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(makeme);
Run Code Online (Sandbox Code Playgroud)
根据你的编辑:对于那种情况,你可以这样做......
var d1 = Type.GetType("GenericTest.TaskA`1"); // GenericTest was my namespace, add yours
Type[] typeArgs = { typeof(Item) };
var makeme = d1.MakeGenericType(typeArgs);
object o = Activator.CreateInstance(makeme);
Run Code Online (Sandbox Code Playgroud)
要查看我在哪里提出了backtick1作为泛型类的名称,请参阅此文章.
注意:如果您的泛型类接受多种类型,则在省略类型名称时必须包含逗号,例如:
Type type = typeof(IReadOnlyDictionary<,>);
Run Code Online (Sandbox Code Playgroud)
实际上你不能写最后一行.
但是你可能不想创建对象,只是为了起见或创建它.您可能想在新创建的实例上调用某个方法.
然后你需要一个类似于界面的东西:
public interface ITask
{
void Process(object o);
}
public class Task<T> : ITask
{
void ITask.Process(object o)
{
if(o is T) // Just to be sure, and maybe throw an exception
Process(o as T);
}
public void Process(T o) { }
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
Type d1 = Type.GetType("TaskA"); //or "TaskB"
Type[] typeArgs = { typeof(Item) };
Type makeme = d1.MakeGenericType(typeArgs);
ITask task = Activator.CreateInstance(makeme) as ITask;
// This can be Item, or any type derived from Item
task.Process(new Item());
Run Code Online (Sandbox Code Playgroud)
在任何情况下,您都不会被静态地转换为您事先不知道的类型(在这种情况下为"makeme").ITask允许您到达目标类型.
如果这不是您想要的,那么您可能需要更加具体地了解您要实现的目标.