Expression.Convert
generalmente arroja InvalidOperationException
cuando "No se define operador de conversión entre expression.Type y type".Expression.Convert no arroja InvalidOperationException para los parámetros de tipo de valor invariable?
El parámetro de tipo de retorno de Func<>
es covariante para los tipos de referencia.
// This works.
Func<SomeType> a =() => new SomeType();
Func<object> b = a;
Es isn't covariant for value types.
La varianza solo se aplica a los tipos de referencia; si especifica un tipo de valor para un parámetro de tipo de variante, ese parámetro de tipo es invariante para el tipo construido resultante.
// This doesn't work!
Func<int> five =() => 5;
Func<object> fiveCovariant = five;
Sin embargo, Expression.Convert
cree que es posible.
Func<int> answer =() => 42;
Expression answerExpression = Expression.Constant(answer);
// No InvalidOperationException is thrown at this line.
Expression converted
= Expression.Convert(answerExpression, typeof(Func<object>));
Sin InvalidOperationException
se lanza al llamar Expression.Convert
. El árbol de expresiones se compila correctamente, pero cuando llamo al delegado creado, obtengo un InvalidCastException
esperado.
- ¿Esto es un error? (I reported it as a bug on Microsoft Connect.)
- ¿Cómo comprobar correctamente si un tipo se puede convertir a otro tipo? Some answers parecen referirse al uso de
Convert
. Preferiría mucho un método que no tenga que usar el manejo de excepciones como lógica.
Parece toda la lógica de la varianza no es soportado adecuadamente. Se queja correctamente de no ser capaz de convertir de Func<SomeType>
a Func<SomeOtherType>
, pero no se queja de la conversión de Func<object>
a Func<string>
.
Curiosamente, una vez SomeType
y SomeOtherType
están en la misma jerarquía de clases (SomeOtherType
se extiende desde SomeType
), nunca se produce la excepción. Si no lo son, lo hace.
_ "Dado dos objetos de tipo, ¿desea saber" _: como en la [documentación de msdn en Expression.Convert] (http://msdn.microsoft.com/en-us/library/bb292051.aspx): _ "Ningún operador de conversión se define entre expression.Type y type." _ En este momento no tengo forma de saber si mi árbol de expresiones representa código válido, hasta ejecutarlo. Para mis propósitos, necesito saber si una conversión implícita es posible. –