Expression.Convert
обычно добавляет InvalidOperationException
, когда "Оператор преобразования не определен между выражением. Тип и тип."
Параметр типа возвращаемого значения Func<>
является ковариантным для ссылочных типов.
// This works.
Func<SomeType> a = () => new SomeType();
Func<object> b = a;
Это не является ковариантным для типов значений .
Дисперсия применяется только к ссылочным типам; если вы указываете тип значения для параметра типа варианта, этот параметр типа является инвариантным для результирующего составного типа.
// This doesn't work!
Func<int> five = () => 5;
Func<object> fiveCovariant = five;
Однако Expression.Convert
считает, что это возможно.
Func<int> answer = () => 42;
Expression answerExpression = Expression.Constant( answer );
// No InvalidOperationException is thrown at this line.
Expression converted
= Expression.Convert( answerExpression, typeof( Func<object> ) );
Нет InvalidOperationException
выбрасывается при вызове Expression.Convert
. Дерево выражений компилируется правильно, но когда я вызываю созданный делегат, я получаю ожидаемое InvalidCastException
.
- Это ошибка? ( Я сообщил об ошибке в Microsoft Connect .)
- Как правильно проверить, можно ли преобразовать тип в другой тип? Некоторые ответы , кажется, относятся к использованию
Convert
. Я бы очень предпочел метод, который не должен использовать обработку исключений в качестве логики.
Кажется, вся логика отклонений не поддерживается должным образом. Он правильно жалуется на невозможность конвертировать из Func<SomeType>
в Func<SomeOtherType>
, но не жалуется на конвертацию из Func<object>
в Func<string>
.
Интересно, что если SomeType
и SomeOtherType
находятся в одной и той же иерархии классов (SomeOtherType
расширяется от SomeType
), исключение не выдается. Если нет, это так.