2011-12-02 21 views
5

Duplicar posibles:
Casting: (NewType) vs. Object as NewType
Casting vs using the 'as' keyword in the CLR¿Cuándo usar() frente a 'como' para cambiar el tipo?

//var gridView = (gridViewRow.NamingContainer as GridView); <-- works too 
var gridView = (GridView)gridViewRow.NamingContainer; 

Mi comprensión incompleta de esto es usar as palabra clave puede dar null cuando se utiliza un molde () va a lanzar una excepción. Mi objetivo es ser capaz de preguntarme "¿qué camino debo elegir?" y saber cómo responderlo.

+1

Esto es un duplicado de muchas veces como, http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr, o http: // stackoverflow.com/questions/2483/casting-newtype-vs-object-as-newtype – Bert

Respuesta

5

Depende, pero básicamente:

Si conoce y puede garantizar que el objeto es el tipo que piensa que a continuación se utilizan ().

Si existe la posibilidad de que sea otra cosa, utilice as y compruebe null. En este caso usted tendría que:

var realThing = someObject as MyClass; 
if (realThing != null) 
{ 
    .... 
} 

Puede utilizar is para custodiar el () lo que resultaría en:

if (someObject is MyClass) 
{ 
    var realThing = (MyClass)someObject; 
    .... 
} 

Pero esto da lugar a dos conversiones, en lugar de la de as o la recto () molde.

Aquí es donde entra el "depende". Tendría que decidir caso por caso, que era más apropiado. Es posible que también tenga estándares de codificación que cumplir.

+0

por curiosidad, ¿qué hay de usar el operador "is" para proteger el uso de()? ¿algo diferente? –

+0

@Gabriel - Ver la actualización. – ChrisF

+2

No debe usar "es" para proteger, ya que entonces realizará 2 conversiones. Si necesita esa funcionalidad, convierta con "como" y busque nulo. –

3

la cuestión es más de

¿Cómo quiero que mi código para hacer frente a un fallo dinámico reparto?

Si usted tiene un contrato implícito/explícito de que gridViewRow.NamingConainer es en realidad una continuación GridView un reparto () es apropiado. Si el tipo no es GridView, se infringe un contrato, se emite una excepción y el error será aparente. Sin embargo, si es posible que no sea un GridView y desee manejar de forma proactiva el caso, entonces es apropiado as.

En este caso, parece que tiene un contrato implícito que es GridView y, por lo tanto, seguiría usando (). Si fue con as y el contrato se rompió, terminaría con un NullReferenceException que no es realmente el problema. El problema es que el tipo no era GridView como se esperaba y, por lo tanto, InvalidCastException es mucho más apropiado

+0

+1 para que la sugerencia considere la claridad del significado de la excepción resultante en el caso de error –

1

Mi regla de oro es que si sé que es del tipo que estoy lanzando a I use() s. Por ejemplo, usaría un lanzamiento directo dentro de un condicional que ya verificó el tipo. Si no estoy seguro, normalmente uso 'como'.

0

Si sabe que gridViewRow.NamingContainer es un GridView, sí, use (GridView) para transmitir. Claramente, el código que sigue no maneja nulo, por lo que si su suposición es incorrecta, obtendrá una excepción de cualquier manera. Usar (GridView) para moldear hará que la excepción sea útil para usted como programador, ya que la excepción mostrará la línea que tiene el error en su rastro de pila.

Si no sabe si gridViewRow.NamingContainer es un GridView, puede combinar el 'if (gridViewRow.NamingContainer es GridView) {... (GridView) gridViewRow.NamingContainer ...}' en un 'como' conversión.

0

De acuerdo con here, la diferencia radica en cómo se manejan los errores en la conversión. Para resumir:

  • () lanzará una excepción si el yeso no es válido, es decir, si la variable no es una subclase de la fundición.
  • as, por el contrario, devolverá un puntero nulo, ofreciendo un rendimiento ligeramente mejor a costa de una depuración más difícil.
Cuestiones relacionadas