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

时间:2022-01-15 16:24:53

I basically have something like this:

我基本上有这样的事情:

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

Foo(typeof(Person));

The Deserialize<ty> doesn't work because it expects Deserialize<Person> instead. How do I work around this?

反序列化 不起作用,因为它期望反序列化 。我该如何解决这个问题?

I'd also like to understand how generics work and why it won't accept ty which is typeof(Person).

我也想了解泛型如何工作以及为什么它不接受类型为(Person)的ty。

EDIT: I ought to have mentioned that this is a contrived example. I cannot actually change the signature of the function because it implements an interface.

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

EDIT: serializer is a JavascriptSerializer and implemented as an action filter here. It is called thusly:

编辑:序列化程序是一个JavascriptSerializer并在此处实现为动作过滤器。因此被称为:

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

Solution

Based on Marc and Anton's answers:

根据Marc和Anton的答案:

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

5 个解决方案

#1


If ty is known at compile-time, why don't just

如果在编译时知道ty,那么为什么不呢

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

Otherwise,

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

#2


Which serializer is that? If you only know the Type at runtime (not compile time), and it doesn't have a non-generic API, then you might have to use MakeGenericMethod:

那个序列化器是什么?如果您只知道运行时的类型(不是编译时),并且它没有非泛型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);
}

#3


Use

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

With the following call

通过以下电话

Foo<Person>();

#4


In this case, just do this:

在这种情况下,只需这样做:

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

Foo<Person>();

Otherwise, you need to call the generic method late-bound, since you have to get the correct generic method for it first (it is not known at compile time). Have a look at the MethodInfo.MakeGenericMethod method.

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

#5


Like Lucero said,

像Lucero说的那样,

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

Foo<Person>();

typeof(Person) is not the same thing as Person. Person is a compile-time type, whereas typeof(Person) is an expression that returns a Type instance representing the runtime type information of Person.

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

#1


If ty is known at compile-time, why don't just

如果在编译时知道ty,那么为什么不呢

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

Otherwise,

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

#2


Which serializer is that? If you only know the Type at runtime (not compile time), and it doesn't have a non-generic API, then you might have to use MakeGenericMethod:

那个序列化器是什么?如果您只知道运行时的类型(不是编译时),并且它没有非泛型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);
}

#3


Use

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

With the following call

通过以下电话

Foo<Person>();

#4


In this case, just do this:

在这种情况下,只需这样做:

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

Foo<Person>();

Otherwise, you need to call the generic method late-bound, since you have to get the correct generic method for it first (it is not known at compile time). Have a look at the MethodInfo.MakeGenericMethod method.

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

#5


Like Lucero said,

像Lucero说的那样,

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

Foo<Person>();

typeof(Person) is not the same thing as Person. Person is a compile-time type, whereas typeof(Person) is an expression that returns a Type instance representing the runtime type information of Person.

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