Мне нужно выполнить неявное и явное приведение типов во время выполнения (с использованием Reflection) для базовых типов и других типов, которые могут существовать в коде (известных во время компиляции), включая классы, структуры и перечисления. Я хочу имитировать компилятор. Он должен быть совместим с Unity, по крайней мере, версии 6, что означает отсутствие некоторых новых функций.
Я использую обходные пути, которые не являются теми, которые мог бы использовать компилятор. Мне бы очень хотелось, чтобы фреймворк мог решать эти приведения типов за меня, вместо поиска в отражении вручную.
Мой вопрос
Я ищу способы заставить компилятор обнаружить тип и сделать то, что он обычно делает во время компиляции. Например:
Код: Выделить всё
public TOut Convert(TIn value) => (TOut)value;
Однако Convert(10f) может быть известен во время компиляции или через MakeGeneric и в некоторой степени возможен. Хотя существуют сценарии, в которых это невозможно (например, Convert). Тогда компилятор этого не позволяет.
Есть ли способ заставить это работать? Наверное, правило? Интерфейс? Другой подход?
Что я уже сделал
- требуется IConvertible. Это не то, что я хочу.
Код: Выделить всё
Convert.ChangeType - — лучший вариант на данный момент.
Код: Выделить всё
public T Implicit(dynamic value) => value; public T Explicit(dynamic value) => (T)value;
Это работает, за исключением нулевых объектов: где компилятор (int)(MyType)(null) вызывает перегрузку op_Explicit, Explicit(default(MyType)) не работает, поскольку null не имеет типа. Других проблем не обнаружил. - Сейчас ищу методы op_Implicit и op_Explicit в типе с помощью GetMethods или GetMember, затем фильтрую список по параметрам. К сожалению, числовые интерфейсы недоступны для примитивных значений в моей версии платформы, поэтому я не могу полагаться на этот подход для примитивных типов. Я вручную составил список возможных приведений типов с помощью лямбда-выражений, разрешающих тип во время компиляции. Опять же, это работает, но я выбрал только 7 примитивов из-за размера класса, тогда это не совсем то, что сделал бы компилятор. И есть класс со всеми парами (int→long, int→float, int→double, long→float, long→double, float→double и т. д.)
- Я искал несколько сообщений (например: этот ответ Джона Скита, который помог с динамикой).