Robin Rodricks
Robin Rodricks

Reputation: 114126

How do I convert a dynamically typed object to a type argument <T> in C#?

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

Answers (1)

Asti
Asti

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

Related Questions