Expression.Convert не выбрасывает InvalidOperationException для параметров типа с неизменным значением?

Expression.Convert вообще бросается в InvalidOperationException, когда "Не определен оператор преобразования между expression.Type и type."

Параметр возвращаемого типа Func является ковариантным для ссылочных типов.

// This works.
Func a = () => new SomeType();
Func b = a;

Он не ковариантен для типов значений.

Вариативность применяется только к ссылочным типам; если вы указываете тип значения для параметра вариативного типа, то этот параметр типа инвариантен для результирующего построенного типа.

// This doesn't work!
Func five = () => 5;
Func fiveCovariant = five;

Однако Expression.Convert считает, что это возможно.

Func answer = () => 42;
Expression answerExpression = Expression.Constant( answer );
// No InvalidOperationException is thrown at this line.
Expression converted 
    = Expression.Convert( answerExpression, typeof( Func ) );

При вызове InvalidOperationException не возникает Expression.Convert. Дерево выражений компилируется правильно, но когда я вызываю созданный делегат, я получаю ожидаемое InvalidCastException.

  1. Это ошибка? (Я сообщил об этом как об ошибке на Microsoft Connect.)
  2. Как правильно проверить, может ли тип быть преобразован в другой тип? В некоторых ответах говорится об использовании Convert. Я бы очень предпочел метод, который не должен использовать обработку исключений в качестве логики.

Похоже, что вся логика дисперсии не поддерживается должным образом. Она правильно жалуется на невозможность преобразования из Func в Func, но не жалуется на преобразование из Func в Func.

Интересно, что если SomeType и SomeOtherType находятся в одной иерархии классов (SomeOtherType extends from SomeType), то исключение не возникает. Если это не так, то выбрасывает.

5
задан Community 23 May 2017 в 12:03
поделиться