Есть ли способ сделать динамическое неявное литье типов в С#?
Учитывая этот класс с неявным оператором литья:
public class MyDateTime
{
public static implicit operator MyDateTime(System.Int64 encoded)
{
return new MyDateTime(encoded);
}
public MyDateTime(System.Int64 encoded)
{
_encoded = encoded;
}
System.Int64 _encoded;
}
Теперь я могу сделать следующее:
long a = 5;
MyDateTime b = a;
Но НЕ следующее:
long f = 5;
object g = f;
MyDateTime h = g;
Это дает время компиляции:
Невозможно неявно преобразовать тип 'object' в 'MyDateTime'.
Имеет смысл для меня.
Теперь я изменяю предыдущий пример следующим образом:
long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;
Это компилируется отлично. Теперь я получаю время выполнения InvalidCastException
:
Невозможно передать объект типа 'System.Int64' для ввода MyDateTime '.
Это говорит мне, что С# неявные операторы литья применяются только во время компиляции и не применяются, когда среда выполнения .NET пытается динамически передать объект другому типу.
Мои вопросы:
- Правильно ли я?
- Есть ли другой способ сделать это?
Кстати, полное приложение состоит в том, что я использую Delegate.DynamicInvoke()
для вызова функции, которая принимает параметр MyDateTime
, а тип аргумента, который я передаю в DynamicInvoke
, длинный.
Ответы
Ответ 1
Правильно ли я?
Да, да. Чтобы быть ничтожным, вы должны сказать "пользовательское неявное преобразование", а не "неявное приведение" - приведение (почти) всегда явное. Но ваш вывод о том, что разрешение перегрузки выбирает, какое пользовательское преобразование для вызова во время компиляции, а не во время выполнения, является правильным.
Есть ли другой способ сделать это?
Да. В С# 4, если вы набираете свой "объект" как "динамический", мы снова запускаем компилятор во время выполнения и повторно выполняем весь анализ операндов, как если бы их типы времени компиляции были текущими типами времени выполнения. Как вы можете себе представить, это не дешево, хотя мы очень умны в кэшировании и повторном использовании результатов, если вы сделаете это в узком цикле.
Ответ 2
Я знаю, что это старый вопрос, но в случае, если кто-то еще сталкивается с той же проблемой, он будет компилироваться и работать нормально:
long f = 5;
object g = f;
MyDateTime h = g as MyDateTime;
Ответ 3
Добавление явного оператора должно работать: http://msdn.microsoft.com/en-us/library/85w54y0a(VS.80).aspx