如何将Type实例转换为泛型类型参数

时间:2009-05-13 08:00:57

标签: c# generics types generic-type-argument

我基本上有这样的事情:

void Foo(Type ty)
{
    var result = serializer.Deserialize<ty>(inputContent);
}

Foo(typeof(Person));

Deserialize<ty>不起作用,因为它需要Deserialize<Person>。我该如何解决这个问题?

我还想了解泛型的工作原理以及它不接受ty typeof(Person)的原因。

编辑:我应该提到这是一个人为的例子。我实际上无法更改函数的签名,因为它实现了一个接口。

编辑:serializer是一个JavascriptSerializer,在这里实现为动作过滤器。因此被称为:

[JsonFilter(Param="test", JsonDataType=typeof(Person))]

解决方案

根据Marc和Anton的答案:

var result = typeof(JavaScriptSerializer).GetMethod("Deserialize")
                 .MakeGenericMethod(JsonDataType)
                 .Invoke(serializer, new object[] { inputContent });

5 个答案:

答案 0 :(得分:7)

是哪个序列化器?如果您只在运行时知道Type(不是编译时),并且它没有非泛型API,那么您可能必须使用MakeGenericMethod

void Foo(Type ty)
{
    object result = typeof(ContainingClass).GetMethod("Bar").
        .MakeGenericMethod(ty).Invoke(null, new object[] {inputContent});
}
public static T Bar<T>(SomeType inputContent) {
    return serializer.Deserialize<T>(inputContent);
}

答案 1 :(得分:6)

如果在编译时知道ty,为什么不只是

void Foo<T>()
{
    var result = serializer.Deserialize<T>(inputContext);
}

否则,

MethodInfo genericDeserializeMethod = serializer.GetType().GetMethod("Deserialize");
MethodInfo closedDeserializeMethod = genericDeserializeMethod.MakeGenericMethod(ty);
closedDeserializeMethod.Invoke(serializer, new object[] { inputContext });

答案 2 :(得分:2)

使用

void Foo<T>(){ var result = serializer.Deserialize<T>(inputContent); }

通过以下电话

Foo<Person>();

答案 3 :(得分:1)

在这种情况下,只需执行此操作:

void Foo<ty>()
{
    var result = serializer.Deserialize<ty>(inputContent);
}

Foo<Person>();

否则,您需要调用泛型方法,因为您必须先获取正确的泛型方法(在编译时不知道)。看看MethodInfo.MakeGenericMethod方法。

答案 4 :(得分:1)

像Lucero说的那样,

void Foo<ty>()
{
    var result = serializer.Deserialize<ty>(inputContent);
}

Foo<Person>();

typeof(Person)与Person不同。 Person是编译时类型,而typeof(Person)是返回表示Person 的运行时类型信息的Type实例的表达式。