Casting: (NewType) vs. Object como NewType

Posible duplicado:
Casting vs usando la palabra clave ‘como’ en el CLR

¿Cuál es en realidad la diferencia entre estos dos moldes?

SomeClass sc = (SomeClass)SomeObject; SomeClass sc2 = SomeObject as SomeClass; 

Normalmente, ambos deberían ser moldes explícitos para el tipo especificado?

El primero emitirá una excepción si el tipo de fuente no se puede convertir al tipo de destino. Esto último dará como resultado que sc2 sea una referencia nula, pero no una excepción.

[Editar]

Mi respuesta original es sin duda la diferencia más pronunciada, pero, como señala Eric Lippert, no es la única. Otras diferencias incluyen:

  • No puede usar el operador ‘as’ para convertir a un tipo que no acepte ‘nulo’ como un valor
  • No puede usar ‘como’ para convertir cosas, como los números en una representación diferente (float to int, por ejemplo).

Y, finalmente, al utilizar ‘como’ frente al operador de reparto, también dices “No estoy seguro de si esto tendrá éxito”.

También tenga en cuenta que solo puede usar la palabra clave as como tipo de referencia o tipo anulable

es decir:

 double d = 5.34; int i = d as int; 

no comstackrá

 double d = 5.34; int i = (int)d; 

comstackrá

La conversión de tipo con “como” es, por supuesto, mucho más rápida cuando falla el lanzamiento, ya que evita el gasto de lanzar una excepción.

Pero no es más rápido cuando el elenco tiene éxito. El gráfico en http://www.codeproject.com/KB/cs/csharpcasts.aspx es engañoso porque no explica lo que está midiendo.

La conclusión es:

  • Si espera que el lanzamiento tenga éxito (es decir, una falla sería excepcional), use un molde.

  • Si no sabe si tendrá éxito, use el operador “as” y pruebe el resultado para nulo.

Una diferencia entre los dos enfoques es que el primero ((SomeClass) obj) puede provocar la llamada de un convertidor de tipo .

Aquí hay una buena manera de recordar el proceso que cada uno de ellos sigue y que uso cuando trato de decidir cuál es mejor para mi circunstancia.

 DateTime i = (DateTime)value; // is like doing DateTime i = value is DateTime ? value as DateTime : throw new Exception(...); 

y el siguiente debería ser fácil de adivinar qué hace

 DateTime i = value as DateTime; 

en el primer caso, si no se puede emitir el valor que arroja una excepción en el segundo caso, si el valor no se puede convertir, i se establece en nulo.

Por lo tanto, en el primer caso se realiza una detención estricta si el yeso falla en el segundo lanzamiento, luego se realiza una detención suave y es posible que se encuentre con una NullReferenceException más adelante.

Bueno, el operador “como” “ayuda” a enterrar tu problema mucho más bajo porque cuando se proporciona una instancia incompatible devolverá nulo, tal vez pasarás eso a un método que pasará a otro y así sucesivamente y finalmente tú ” Obtendré una NullReferenceException que dificultará la depuración.

No abusar de eso El operador de lanzamiento directo es mejor en el 99% de los casos.

Para ampliar el comentario de Rytmis , no puede usar la palabra clave as para estructuras (tipos de valores), ya que no tienen valor nulo.

Todo esto se aplica a los tipos de referencia, los tipos de valores no pueden usar la palabra clave como, ya que no pueden ser nulos.

 //if I know that SomeObject is an instance of SomeClass SomeClass sc = (SomeClass) someObject; //if SomeObject *might* be SomeClass SomeClass sc2 = someObject as SomeClass; 

La syntax de conversión es más rápida, pero solo cuando tiene éxito, es mucho más lento para fallar.

La mejor práctica es usarla cuando no se conoce el tipo:

 //we need to know what someObject is SomeClass sc; SomeOtherClass soc; //use as to find the right type if( ( sc = someObject as SomeClass ) != null ) { //do something with sc } else if ( ( soc = someObject as SomeOtherClass ) != null ) { //do something with soc } 

Sin embargo, si está absolutamente seguro de que someObject es una instancia de SomeClass , utilice cast.

En .Net 2 o superior generics significa que muy rara vez necesita tener una instancia no tipada de una clase de referencia, por lo que este último se utiliza con menos frecuencia.

El lanzamiento entre paréntesis arroja una excepción si el bash de lanzamiento falla. El lanzamiento “como” devuelve nulo si falla el bash de lanzamiento.

Lanzarán diferentes excepciones.
() : Excepcion de referencia nula
como: InvalidCastException
Lo que podría ayudar a la depuración.

La palabra clave “como” intenta lanzar el objeto y si el molde falla, null se devuelve en silencio. El operador de conversión lanzará una excepción de inmediato si el lanzamiento falla.

“Solo use la palabra clave C #” como “donde espera que el lanzamiento falle en un caso no excepcional. Si está contando con un elenco para tener éxito y no está preparado para recibir cualquier objeto que fallaría, debería usar el () operador de reparto para que se produzca una excepción apropiada y útil “.

Para ejemplos de código y una explicación adicional: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

Es como la diferencia entre Parse y TryParse. Usas TryParse cuando esperas que pueda fallar, pero cuando tienes una gran seguridad de que no fallará, usas Parse.

Para aquellos de ustedes con experiencia en VB.NET, (tipo) es lo mismo que DirectCast y “como tipo” es lo mismo que TryCast.

Y para completar, Eric Lippert tiene una publicación en el blog sobre la diferencia y algunas advertencias.