2010-08-19 14 views
11

Encuentro este comportamiento de TryCast en .NET 4.0/VS 2010 bastante confuso.TryCast falla donde funciona DirectCast (.NET 4.0)

Según tengo entendido, TryCast funciona como DirectCast, pero devolverá Nothing en lugar de lanzar una excepción si no se puede realizar un lanzamiento.

VS 2010/.NET 4

?TryCast(CType(1, Object), String) 
Nothing 
?DirectCast(CType(1, Object), String) 
"1" 

VS 2008/.NET 3,5

?TryCast(CType(1, Object), String) 
Nothing 
?DirectCast(CType(1, Object), String) 
Cannot convert to 'String'. 

El .NET 3.5 resultados son consistentes con lo que creo TryCast hace ... .NET 4 sin embargo no lo es.

¿Puede alguien indicarme la mejor dirección para lanzar un objeto de forma segura a String en .NET 4?

Respuesta

16

De acuerdo con las muestras de código que comienzan con ? Supongo que está utilizando la ventana inmediata para realizar la prueba correcta. El problema con este enfoque es que la ventana inmediata es una interpretación en lugar de una evaluación real. Esto lo deja susceptible a errores sutiles en las esquinas y este es de hecho uno de ellos.

Si toma su código de muestra y lo agrega a una simple aplicación de consola VB.Net, encontrará que el comportamiento de 2010 es idéntico al de 2008 (arroja una excepción).

EDITAR

Entonces, ¿por qué sucedió esto regresión? En 2010 reescribí por completo el motor de depuración VB EE (evaluador de expresiones). La antigua base de código que heredé era simplemente demasiado costosa de mantener. Hasta el punto de agregar nuevas características al motor era más costoso que reescribirlo desde cero con una mejor arquitectura que incluyera las nuevas características.

Como dije antes de las evaluaciones de depuración es una interpretación más que una ejecución de código. Fuerza la duplicación de algunos algoritmos entre EE y CLR/Compiler. Una de las áreas donde ocurre la duplicación es en la lógica de lanzamiento. No hay forma de pedirle al depurador de CLR que emita un objeto de tiempo de depuración, es responsabilidad del EE determinar si el lenguaje especificado es realmente válido.

La antigua lógica de conversión de EE tenía numerosos errores (especialmente en el área de genéricos y matrices). La infraestructura más nueva se ajusta muy de cerca a las pautas de CLR. Sin embargo, nunca tendrá el 100% de paridad porque no permitiría expresiones muy útiles en EE (puedo escribir una publicación de blog sobre esto en el futuro). Pero para la mayoría de los casos, el comportamiento se cumple.

En esta instancia particular, agregué un error sutil que permite un cálculo directo de un valor que se escribe en Object para utilizar los operadores de conversión en tiempo de ejecución de VB frente al comportamiento especificado que solo permite conversiones CLR. Por lo tanto, esta conversión tiene éxito donde debería fallar.

+0

Acabo de confirmar lo que sugirió. DirectCast() arroja una excepción cuando se ejecuta en una evaluación real. ¡Gracias por la aclaración! – motto

+0

Sería realmente bueno si pudieras explicar exactamente lo que sucedió. – SLaks

+0

@SLaks, agregó una explicación rápida. – JaredPar