try safe que objetos convert cast c# .net

c# - safe - Casting:(NewType) vs. Object como NewType



string to object c# (12)

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

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

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

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


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

DateTime i = value as DateTime;

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

Entonces, en el primer caso, se realiza una parada difícil si el lanzamiento falla en el segundo lanzamiento, se realiza una parada suave y es posible que encuentre una NullReferenceException más adelante.


Bueno, el operador ''como'' "te ayuda" a enterrar tu problema mucho más bajo porque cuando se proporciona una instancia incompatible, volverá nulo, tal vez lo pasarás a un método que lo pasará a otro y así sucesivamente y finalmente '' obtendrá una NullReferenceException que hará que su depuración sea más difícil.

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


El primero arrojará 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 ciertamente la diferencia más pronunciada, pero como señala Eric Lippert, no es la única. Otras diferencias incluyen:

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

Y finalmente, usando ''as'' contra el operador de reparto, también estás diciendo "No estoy seguro de si esto tendrá éxito".


El reparto entre paréntesis arroja una excepción si el intento de lanzamiento falla. El lanzamiento "as" devuelve nulo si el intento de lanzamiento falla.


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


La conversión de texto usando "as" 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 reparto 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, un fracaso sería excepcional), use un lanzamiento.

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


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

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

"Solo use la palabra clave C" como "cuando espera que el lanzamiento falle en un caso no excepcional. Si cuenta con un lanzamiento exitoso y no está preparado para recibir cualquier objeto que falle, debe usar el () emitir operador 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


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


Para aquellos de ustedes con experiencia en VB.NET, (type) es lo mismo que DirectCast y "as type" es lo mismo que TryCast.


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

es decir:

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

no compilará

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

Se compilará.


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

La mejor práctica es usar as cuando no 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 , use cast.

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.


Una diferencia entre los dos enfoques es que el primer ((SomeClass) obj) puede hacer que se llame a un convertidor de tipos .