2010-03-31 10 views
15

Duplicar posible:
Casting vs using the ‘as’ keyword in the CLREmitir luego verificar o verificar y luego emitir?

¿Qué método se considera como una buena práctica?

Reparto primero?

public string Describe(ICola cola) 
{ 
    var coke = cola as CocaCola; 
    if (coke != null) 
    { 
     string result; 
     // some unique coca-cola only code here. 
     return result; 
    } 
    var pepsi = cola as Pepsi; 
    if (pepsi != null) 
    { 
     string result; 
     // some unique pepsi only code here. 
     return result; 
    } 
} 

¿O debería comprobar primero, emitir luego?

public string Describe(ICola cola) 
{ 
    if (cola is CocaCola) 
    { 
     var coke = (CocaCola) cola; 
     string result; 
     // some unique coca-cola only code here. 
     return result; 
    } 
    if (cola is Pepsi) 
    { 
     var pepsi = (Pepsi) cola; 
     string result; 
     // some unique pepsi only code here. 
     return result; 
    } 
} 

¿Puedes ver alguna otra forma de hacer esto?

+0

Ver la respuesta perfecta http: // stackoverflow.com/a/496167/52277 para una pregunta similar –

Respuesta

19

Si el objeto puede o no puede ser del tipo que quieres, entonces el operador as (el primer método) es mejor en dos formas:

  • de legibilidad y facilidad de mantenimiento: solo está especificando el tipo una vez
  • Rendimiento: solo está realizando el lanzamiento una vez, en lugar de dos veces. (Anécdota:. Cuando se utiliza la palabra clave is, el compilador de C# se traduce internamente a as, es decir coke is Cola es equivalente a (coke as Cola) != null)

Si el objeto debe ser siempre del tipo solicitado a continuación, sólo hacer (Coke)cola y dejar que se lanza una excepción si ese no es el caso.

7

La primera (transmisión primero a través de as) es ligeramente más eficiente, por lo que en ese sentido, podría ser una buena práctica.

Sin embargo, el código anterior, en general, muestra un poco de "olor a código". Consideraría refactorizar cualquier código que siga este patrón, si es posible. Tener ICola proporcionar un método de descripción, y dejar que se describa a sí mismo. Esto evita los controles de tipo y código duplicado ...

+0

Estoy de acuerdo con el olor del código: en el ejemplo, esto parece un problema que podría resolverse mejor mediante polimorfismo en lugar de lanzar objetos de forma salvaje. –

+0

Estoy de acuerdo con el olor del código. Sin embargo, en este caso, no quiero que los métodos impregnen mis objetos Cola. – jamesrom

+1

@jamesrom: Bueno, intenté responder a su pregunta, primero, antes de mencionar eso (ya que es más rápido). Sin embargo, realmente pensaría en cómo podría eliminar el código duplicado. ¿Puede su pase de visualización en un delegado manejar el código "específico" más eficientemente, tal vez? –

3

creo que es más eficiente primera manera: moldeada y después comprobar, pero ...

Un montón de tiempo a desarrollar para los desarrolladores, y en mi opinión, es mucho más fácil de leer comprobar primero y luego fundición ...

+0

buen punto ........... – nawfal

4

Este ejemplo utiliza un parámetro local que es seguro, pero muchas veces la verificación de tipo se aplica a los campos (variables de miembro) de una clase. En ese caso, "como" -then-check es seguro, pero "is" -entonces-cast crea una condición de carrera gratuita.

1

Permítanme ponerlo por ahí. Pero creo que ninguno está bien :) En tu ejemplo particular, ¿por qué tener una interfaz entonces? Pondría un método de "Describir" en su interfaz ICola, luego implementaría la lógica de descripción en sus clases CocaCola y Pepsi que implementan la interfaz.

Así que, básicamente, poner ese // some unique <some cola> only code here. en las clases de implementación.

Pero para responder a su pregunta, creo que Check-then-cast es más apropiado.

+0

Eso es lo que haría si pudiera. Pero di, por ejemplo, que no quería que mi lógica de vista impregnara mis objetos Cola. – jamesrom

+0

En ese caso, use algún decorador o solución basada en visitante, por ejemplo, cualquier cosa es mejor que inspeccionar manualmente el tipo de objetos en tiempo de ejecución. Incluso creo que la lógica de vista sería menos malvada que el fundido y el encendido de tipos en todo el lugar. – kai

Cuestiones relacionadas