Pregunta

Posible duplicado:
Transmitir versus usar la palabra clave 'as' en CLR

¿Cuál es realmente la diferencia entre estos dos elencos?

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

Normalmente, ¿ambos deberían ser conversiones explícitas al tipo especificado?

¿Fue útil?

Solución

El primero generará una excepción si el tipo de origen 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 Eric Lippert Señala, no es el único.Otras diferencias incluyen:

  • No puede utilizar el operador 'como' para convertir a un tipo que no acepta 'nulo' como valor
  • No puedes usar 'como' para convertir cosas, como números a una representación diferente (float a int, por ejemplo).

Y finalmente, usar 'como' vs.Al operador de reparto, también le estás diciendo "No estoy seguro de si esto tendrá éxito".

Otros consejos

También tenga en cuenta que solo puede utilizar la palabra clave as con un tipo de referencia o un tipo que acepta valores NULL.

es decir:

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

no compilará

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

compilará.

Por supuesto, encasillar usando "as" es mucho más rápido cuando la conversión falla, ya que evita el gasto de generar una excepción.

Pero no es más rápido cuando el lanzamiento 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 elenco tenga éxito (es decir,un fracaso sería excepcional), utilice un yeso.

  • Si no sabe si tendrá éxito, utilice el operador "as" y pruebe si el resultado es nulo.

Una diferencia entre los dos enfoques es que el primer ((SomeClass)obj) puede causar un convertidor de tipo ser llamado.

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

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 lo que hace

DateTime i = value as DateTime;

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

Entonces, en el primer caso se realiza una parada brusca si la conversión falla, en el segundo se realiza una parada suave y es posible que se encuentre con una excepción NullReferenceException más adelante.

Bien el operador 'as' te "ayuda" a enterrar tu problema mucho más bajo porque cuando se proporciona una instancia incompatible devolverá nulo, tal vez lo pase a un método que lo pasará a otro y así sucesivamente y finalmente obtendrá una excepción NullReferenceException que dificultará la depuración.

No abuses de ello.El operador de reparto directo es mejor en el 99% de los casos.

Para ampliar El comentario de Rytmis., no puedes usar el como palabra clave para estructuras (tipos de valores), ya que no tienen ningún valor nulo.

Todo esto se aplica a los tipos de referencia, los tipos de valor no pueden usar el as palabra clave 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 sintaxis de conversión es más rápida, pero solo cuando tiene éxito, es mucho más lento fallar.

La mejor práctica es utilizar as cuando no sabes 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ás absolutamente seguro de que someObject es una instancia de SomeClass luego usa yeso.

En .Net 2 o superior, los genéricos significan que rara vez es necesario tener una instancia sin tipo de una clase de referencia, por lo que esta última se usa con menos frecuencia.

La conversión entre paréntesis genera una excepción si el intento de conversión falla.La conversión "as" devuelve nulo si el intento de conversión falla.

Lanzarán diferentes excepciones.
() :Excepcion de referencia nula
como :Excepción de transmisión no válida
Lo que podría ayudar a la depuración.

La palabra clave "as" intenta convertir el objeto y, si la conversión falla, se devuelve nulo en silencio.El operador de conversión () generará una excepción inmediatamente si la conversión falla.

"Utilice únicamente la palabra clave C# "as" cuando espere que la conversión falle en un caso no excepcional.Si cuenta con que una conversión tendrá éxito y no está preparado para recibir cualquier objeto que falle, debe utilizar el operador de conversión () para que se genere una excepción adecuada 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.Utiliza TryParse cuando espera que pueda fallar, pero cuando tiene una gran seguridad de que no fallará, usa Parse.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top