Есть ли способ сделать динамическое неявное приведение типов в C #? - PullRequest
11 голосов
/ 19 января 2010

Учитывая этот класс с неявным оператором приведения:

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 пытается динамически привести объект к другому типу.

Мои вопросы:

  1. Я прав?
  2. Есть ли другой способ сделать это?

Кстати, полное приложение состоит в том, что я использую Delegate.DynamicInvoke() для вызова функции, которая принимает MyDateTimeпараметр, и тип аргумента, который я передаю DynamicInvoke, является длинным.

Ответы [ 3 ]

14 голосов
/ 19 января 2010

Я прав?

Да, да. Чтобы быть придирчивым, вы должны говорить «неявное преобразование, определенное пользователем», а не «неявное приведение» - приведение (почти) всегда явное. Но ваш вывод о том, что разрешение перегрузки выбирает, какое пользовательское преобразование будет вызывать во время компиляции , а не во время выполнения , является правильным.

Есть ли другой способ сделать это?

Да. В C # 4, если вы вводите свой «объект» как «динамический», мы снова запускаем компилятор во время выполнения и повторно выполняем весь анализ операндов , как если бы их типы во время компиляции были текущие типы времени выполнения . Как вы можете себе представить, это недешево, хотя мы очень умны в отношении кэширования и повторного использования результатов, если вы сделаете это в тесном цикле.

0 голосов
/ 30 января 2013

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

long f = 5;
object g = f;
MyDateTime h = g as MyDateTime;
0 голосов
/ 19 января 2010

Добавление явного оператора должно работать: http://msdn.microsoft.com/en-us/library/85w54y0a(VS.80).aspx

...