如何使用反射动态创建通用C#对象?

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)

  • 感谢您链接到我的博客文章"使用反射在C#.Net中实例化通用类"(http://omegacoder.com/?p=38)作为"简单示例".:-)我很高兴这篇文章找到了新生活. (7认同)
  • Francis Dean,重点是你有 Type 对象,但你不能将 is 放在 &lt;&gt; 中 (2认同)

Jer*_*ban 8

实际上你不能写最后一行.

但是你可能不想创建对象,只是为了起见或创建它.您可能想在新创建的实例上调用某个方法.

然后你需要一个类似于界面的东西:

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允许您到达目标类型.

如果这不是您想要的,那么您可能需要更加具体地了解您要实现的目标.