从字符串中实例化泛型类型

时间:2013-06-24 14:26:55

标签: c# generics

我想Instantiate a generic type from string并做了以下事情:

    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指令或汇编引用?)”但我想根据找到的字符串实例化Serializer。我怎么能这样做?

3 个答案:

答案 0 :(得分:1)

您已拥有通用类型,其中包含以下内容:

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

您需要做的就是实例化它:

object o = ACtivator.CreateInstance(t);

当然编译器不知道t是什么类型,因此如果没有反射,你将无法使用它的方法/属性,因此泛型并不能真正帮助你。你可以做的最好的是转换为Serializer<>的非通用基类(假设存在一个)。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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

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

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

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

3)创建临时generict方法并用反射调用它(你有智能感知和编译时检查):

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&lt;临时方法&lt; simpleReflection