Как преобразовать динамически типизированный объект в аргумент типа <T>в C#? - PullRequest
1 голос
/ 13 апреля 2020

Я часами гуглял, а также нашел различные вопросы о переполнении стека, но ни один из них не соответствовал моему точному варианту использования. Это то, что у меня есть: метод, который принимает 2 общих параметра типа c. Библиотека с закрытым исходным кодом, поэтому я не могу ее изменить. Подпись метода выглядит следующим образом:

 TTo Convert<TFrom, TTo>(TFrom obj)

Однако, когда вы вызываете это, вы всегда должны указывать оба параметра типа, например:

Convert<Dog, Cat>(dog);

Я пытаюсь поддержать использование случай, когда предоставляется только параметр типа назначения:

Convert<Cat>(dog);

Итак, мне нужна следующая сигнатура метода:

TTo Convert<TTo>(object obj){
     var TFrom = obj.GetType();
     Convert<TFrom, TTo>((TFrom)obj); // <--- throws an error right here
}

Можете ли вы помочь мне исправить это? В этом ответе SO упоминаются конструкторы лямбда-выражений , но я не уверен, как это сделать в этом случае использования. Этот SO-ответ упоминает Dynami c, набрав , но это не то, что мне нужно здесь.

Редактировать: связанный "дубликат" вопрос приходит close, но он обрабатывает только динамическое приведение типов generi c для обычных аргументов метода, но не обрабатывает аргументы TYPE, что мне и нужно.

1 Ответ

3 голосов
/ 13 апреля 2020

Это можно сделать с помощью Reflection. Вам просто нужно создать метод с примененными параметрами типа.

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

Использование:

ConvertObject<int>(1.0f); //prints I was called with 1

null передается, потому что метод был статическим; он должен быть заменен экземпляром, который содержит метод Convert, а также типом, содержащим метод.

...