Учитывая этот класс с неявным оператором литом:Есть ли способ сделать динамическое неявное литье типов в C#?
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 '.
Это говорит о том, что C# неявные операторы литья применяются только во время компиляции и не применяются, когда среда выполнения .NET пытается динамически отличать объект от другого типа.
Мои вопросы:
- я правильно?
- Есть ли другой способ сделать это?
Кстати, полное приложение является то, что я использую Delegate.DynamicInvoke()
для вызова функции, которая принимает параметр MyDateTime
и тип аргумента я передаю к DynamicInvoke
длинный.
Просто из любопытства, каковы причины, по которым операторы не ведут себя как методы во время выполнения? Учитывая ваш ответ, кажется, что они всего лишь синтаксический сахар и не намного больше. На мой взгляд, это сделает C# еще более мощным, если такие операторы будут продвигаться как первоклассный член любого типа (что означает, что они становятся частью всего другого объектно-ориентированного добра, такого как наследование, переопределение и взаимодействие). Посредством использования этих средств во время выполнения по умолчанию подразумеваются значительные изменения в дизайне и внедрении языка? – MarioDS
@MDeSchaepmeester: Вы правы, что здесь есть немного разъединения. Сравните дизайн int с десятичным, например. Вы можете сказать 'Func add = decimal.Add;', но нет способа сделать то же самое для int; вы должны сказать 'Func add = (x, y) => x + y'. Было бы неплохо, если бы все встроенные типы были разработаны как Decimal, а затем среда выполнения или компилятор могли бы выбрать, чтобы снизить их до более фундаментальных операций по соображениям производительности. Но такая последовательность последовательно вытекает из «функционального» мышления. –
@MDeSchaepmeester: Я подозреваю, что оригинальные дизайнеры среды выполнения просто не думали об этом объединении функциональной абстракции при проектировании системы типов и операций над встроенными типами. И, конечно, также нечетно, что в десятичной системе есть как оператор +, так и метод Add. И даже не заставляйте меня начинать с дюжины способов представления операции равенства! Это действительно беспорядок. В следующий раз, когда вы создадите структуру с нуля, сначала получите это. –