2009-02-20 10 views
7

me parece que el uso de los siguientes:¿Hay razones de peso EN CONTRA de usar la palabra clave C# "como"?

TreeViewItem i = sender as TreeViewItem; 
if(i != null){ ... } 

es más fácil de escribir y entender que:

if(sender.GetType() == typeof(TreeViewItem)){ 
    TreeViewItem i = (TreeViewItem)sender; 
    ... 
} 

¿Hay razones de peso no utilizar la primera construcción?

+0

sender.GetType() == typeof (TreeViewItem) no es lo mismo que 'emisor como TreeViewItem'. Esa prueba no tiene en cuenta la jerarquía de herencia, algo como 'como' y 'es' la palabra clave. –

+0

Dupe? http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr/496167#496167 –

Respuesta

12

Prefiero los moldes a as en la mayoría de los casos porque generalmente si el tipo de objeto es incorrecto, eso indica un error. Los errores deberían causar excepciones IMO - y InvalidCastException exactamente en la línea que realiza el reparto es mucho más claro que NullReferenceException mucho más tarde en el código.

as se debe utilizar cuando es válido y legal que se haya pasado una referencia a un objeto del tipo que no desea. Esa situación se presenta, pero no tan a menudo como el casting normal en mi experiencia.

tipos Comparando utilizando GetType(), sin embargo, es muy rara la solución correcta - que es muy apropiada cuando se quiere comprobar si el tipo exacto involucrados en lugar de un tipo compatible.

He escrito un significantly longer answer sobre la discusión "cast vs as" en otro lugar.

7

No, en absoluto, le da la oportunidad de verificar que la conversión (conversión) se haya realizado correctamente. Si lo hace

TreeViewItem i = (TreeViewItem) sender; 

es posible que obtenga una excepción si el molde falla.

4

"as": cosas buenas. Úsalo todo el tiempo.

si realmente quieres una alternativa a la comparación manual de tipos Proveedores:

if(person is Employee) { } 

lee mejor aún.

1

"como" es más rápido, pero las cosas a tener en cuenta son:

  • "como" devuelve un valor nulo en lugar de lanzar una excepción si eso es un problema

  • no lo hará conversiones personalizadas IIRC

  • que no funciona para referencia-> valor

Editar: "como" sin duda es más rápido (http://www.codeproject.com/KB/cs/csharpcasts.aspx)

Edit2: así que básicamente una velocidad vs decisión seguridad

1

No, lo uso bastante. Le permite evitar InvalidCastException s de una manera limpia.

Por ejemplo:

TreeViewItem tvItem = sender as TreeViewItem; 

if (tvItem != null) return; 

// Do stuff 

en contraposición a:

try 
{ 
    TreeViewItem tvItem = (TreeViewItem)sender; 
    // Do stuff. 
} 
catch (InvalidCastException ex) 
{ 
    // Didn't work, do something about it 
    return; // ... or not... 
} 
+0

¿Puede pensar en alguna razón que "remitente" no sería un TreeViewItem otro que un error, en la mayoría de los casos? Los errores * deberían * elevar excepciones IMO. –

4

Su ejemplo sería mejor escribir como:

if (sender is TreeViewItem) { 
    TreeViewItem i = (TreeViewItem)sender; 
    ... 
} 

Es exactamente este tipo dual de comprobar que el as el operador puede ayudar a evitar. Entonces, para su ejemplo citado, diría que definitivamente es una buena solución.

Sin embargo, hay situaciones en las que realmente hacen quieren un yeso. Si esperas un TreeViewItem y no deseas nada más, el lanzamiento garantizará que se genere un InvalidCastException si se te proporciona algo más.

Al igual que en la mayoría de las situaciones, no hay una regla general aquí: utilice la herramienta adecuada para el trabajo correcto.

+0

¡Tu alternativa a mi ejemplo es mejor, gracias! – Pwninstein

+0

Este formulario también puede causar problemas cuando se multiplique, ya que el objeto puede cambiar el tipo entre el control de lanzamiento y el lanzamiento regular. –

2

Si desea una llanura (no anulable) tipo de valor, obviamente, esto no funciona, por ejemplo:

int test = sender as int; 

no es válida, sin embargo: se permite

int? test = sender as int?; 

.

6

En general, estos dos fragmentos son no equivalente. TreeViewItem i = sender as TreeViewItem producirá un resultado correcto incluso si sender es un grand-grand-niño de TreeViewItem, mientras que sender.GetType() == typeof(TreeViewItem) habrá truesolamente cuando sender es precisamente TreeViewItem y ninguno de sus posibles subclases.

1

Si obtener un tipo incorrecto sería un error, entonces debería usar un molde. La razón de esto es que realmente hay un problema y debes saberlo.

Si es posible que el valor sea nulo, y eso no es un error en el sistema cuando esto sucede, utilice "como". La razón es que debe usar "como" en cualquier momento que sea aceptable obtener una nula vuelta.

Tenga en cuenta que no puede usar "como" para convertir tipos de valores, porque el valor nulo no es aceptable para ellos. Si tiene un tipo de valor y desea usar "como", deberá usar un tipo de valor que admite valores.

When to Use "as" Versus Casting

Cuestiones relacionadas