Tutorial :How to turn a Type instance into a generic type argument



Question:

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).

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:

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

Solution

Based on Marc and Anton's answers:

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


Solution:1

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

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 });  


Solution: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:

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);  }  


Solution:3

Use

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

With the following call

Foo<Person>();  


Solution: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.


Solution:5

Like Lucero said,

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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »