从字符串实例化泛型类型

本文关键字:泛型类型 实例化 字符串 | 更新日期: 2023-09-27 18:19:45

我想从字符串实例化一个泛型类型,并完成了以下操作:

    private static void APERAK(string content, PartyElement pe, bool reload)
    {
        Type t = typeof(Serializer<>).MakeGenericType(Type.GetType(GetMessageTypeVersion(content)));
        Serializer<t> serializer = new Serializer<t>();
    }
    private static string GetMessageTypeVersion(string content)
    {
        //TODO
        return "APERAK";
    }

但在

Serializer<t> serializer = new Serializer<t>();

它说在编译之前"找不到类型或命名空间名称't'(是否缺少using指令或程序集引用?)"。但我想根据找到的字符串实例化序列化程序。我该怎么做?

从字符串实例化泛型类型

您已经有了一个具有以下内容的泛型类型:

typeof(Serializer<>).MakeGenericType(...);

您所需要做的就是实例化it:

object o = ACtivator.CreateInstance(t);

当然,编译器不知道t是什么类型,因此您将无法在没有反射的情况下使用其方法/属性,因此泛型在这里对您没有真正的帮助。您能做的最好的事情就是强制转换为Serializer<>的非泛型基类(假设存在)。

泛型是一个编译时构造。您必须在编译时知道类型参数是什么,而不是在运行时。

所以,你真的不可能获得编译时泛型的所有功能。好吧,还有其他一些方法。

1) 实例化泛型类型并将其打包为对象,然后使用反射调用方法:

object t = Activator.CreateInstance(type);
var res = (string)type.GetMethod("Do").Invoke(t, new object[] { "abc" });

2) 实例化泛型类型并将其转换为动态对象,然后只使用它(您将失去intellisense和编译时检查):

dynamic t = Activator.CreateInstance(type);
var res = (string)(t.Do("abc"));

3) 创建临时泛型方法并使用反射调用它(您可以进行intellisense和编译时检查):

public static string UseSerializer<T>(Serializer<T> s)
{
   return s.Do("abc");
}

然后以这样的方式使用它:

var useSerializer = typeof(SomeStaticClass).GetMethod("UseSerializer")
object t = Activator.CreateInstance(type);
var res = useSerializer.Invoke(null, new object[]{t});

此外,这些方法可以按执行时间排序:dynamic<临时方法<simpleReflection