Reputation: 114126
I've googled for hours and also found various stackoverflow questions but none cater to my exact use-case. This is what I have: a method that takes 2 generic type parameters. The library is closed source so I cannot modify it. The method signature looks like:
TTo Convert<TFrom, TTo>(TFrom obj)
However when you call this you always have to provide both type parameters, like this:
Convert<Dog, Cat>(dog);
I'm trying to support a use-case where only the destination type parameter is provided:
Convert<Cat>(dog);
So the method signature I need is as follows:
TTo Convert<TTo>(object obj){
var TFrom = obj.GetType();
Convert<TFrom, TTo>((TFrom)obj); // <--- throws an error right here
}
Can you help me fix this? This SO answer mentions using Lambda expression builders but I'm not sure how to do that in this use case. This SO answer mentions dynamic typing but its not what I need here.
Edit: The linked "duplicate" question comes close but it only handles dynamically casting generic types for regular method arguments, but doesn't handle TYPE arguments which is what I need.
Upvotes: 1
Views: 568
Reputation: 12687
This can be accomplished with Reflection. You just need to construct a method with your type parameters applied.
class Program
{
public static TTo Convert<TFrom, TTo>(TFrom obj)
{
Console.WriteLine($"I was called with {obj}");
return default;
}
public static TTo ConvertObject<TTo>(object obj)
{
var method = typeof(Program).GetMethod(nameof(Convert));
var specialized = method.MakeGenericMethod(new[] { obj.GetType(), typeof(TTo) });
return (TTo) specialized.Invoke(null, new[] { obj });
}
}
Usage:
ConvertObject<int>(1.0f); //prints I was called with 1
The null
is passed because the method was static; that should be substituted with the instance which contains the Convert
method, as well as the type containing the method.
Upvotes: 3