将实例化的System.Type作为泛型类的类型参数传递

Rob*_*rth 174 .net c# generics

标题有点模糊.我想知道的是,如果可能的话:

string typeName = <read type name from somwhere>;
Type myType = Type.GetType(typeName);

MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();
Run Code Online (Sandbox Code Playgroud)

显然,MyGenericClass被描述为:

public class MyGenericClass<T>
Run Code Online (Sandbox Code Playgroud)

现在,编译器抱怨'找不到类型或命名空间'myType'."必须有办法做到这一点.

Jon*_*eet 211

没有反思,你不能这样做.但是,你可以用反射来做.这是一个完整的例子:

using System;
using System.Reflection;

public class Generic<T>
{
    public Generic()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
}

class Test
{
    static void Main()
    {
        string typeName = "System.String";
        Type typeArgument = Type.GetType(typeName);

        Type genericClass = typeof(Generic<>);
        // MakeGenericType is badly named
        Type constructedClass = genericClass.MakeGenericType(typeArgument);

        object created = Activator.CreateInstance(constructedClass);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您的泛型类接受多种类型,则在省略类型名称时必须包含逗号,例如:

Type genericClass = typeof(IReadOnlyDictionary<,>);
Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);
Run Code Online (Sandbox Code Playgroud)

  • 每当我赞成Jon Skeet时,我都觉得自己已被剥夺了灵魂中的一小部分.:( (18认同)
  • 好吧,如果你可以让你的泛型类型实现非泛型接口,你可以转换为该接口.或者,您可以编写自己的泛型方法,该方法执行您要对泛型执行的所有工作,并使用反射调用*that*. (7认同)
  • @ RobertC.Barth您还可以在示例类型"动态"而不是"对象"中创建"已创建"对象.这样你就可以在其上调用方法,并且评估将推迟到运行时. (5认同)
  • @balanza:您使用MakeGenericMethod. (3认同)
  • 好的,这很好,但是如何调用创建的方法呢?更多反思? (2认同)

Jar*_*Par 14

不幸的是没有.通用参数必须在编译时可解析为1)有效类型或2)另一个通用参数.如果没有使用反射的大麻烦,就无法基于运行时值创建泛型实例.