2010-02-14 7 views
5

¿Cuál es su perspectiva sobre el downcasting? ¿SIEMPRE está mal, o hay casos en que es aceptable, o incluso preferible o deseado?¿El lanzamiento descendente (es decir, el fundido al tipo derivado) SIEMPRE está mal?

¿Hay alguna buena medida/directriz que podamos dar que nos diga cuándo el downcasting es "malo", y cuándo está "bien"/"bien"?

(sé a similar question exists, pero esa pregunta se sale de un caso concreto. Me gustaría tener que respondió desde una perspectiva de diseño general.)

+2

nada es __ALWAYS__ incorrecto, bueno excepto gotos y optimización prematura sin perfilar primero. :-) –

+0

Bien, tal vez debería haber reformulado mi encabezado. ;) Estaba buscando (preferiblemente un conjunto de) casos en los que sería "bueno"/"malo". –

+1

Si los gotos son tan incorrectos, ¿por qué Java usa saltos largos para sus excepciones? Incluso las declaraciones que se usan mal tienen su propósito ... – Scharrels

Respuesta

8

No, definitivamente no es siempre mal.

Por ejemplo, supongamos que en C# tiene un controlador de eventos - que obtiene un parámetro sender, que representa el originador del evento. Ahora puede conectar ese controlador de eventos a varios botones, pero sabe que son siempre botones. Es razonable emitir sender a Button dentro de ese código.

Es solo un ejemplo: hay muchas otras. A veces es solo una manera de evitar una API un poco incómoda, otras veces se trata de no poder expresar el tipo dentro del sistema de tipo normal limpiamente. Por ejemplo, puede tener un Dictionary<Type, object> encapsulado apropiado, con métodos genéricos para agregar y recuperar valores, donde el valor de una entrada es del tipo de la clave. Aquí, el reparto es completamente natural: se puede ver que siempre funcionará, y le da más seguridad al resto del sistema.

+0

Es verdad, Jon, pero ¿no se pudo (al menos en parte) evitar el caso de los eventos C# con la introducción de tipos co/contravariantes? Podrías conectarte a, por ejemplo, un controlador (Button, ButtonEventArgs) si estaba enganchado a un botón, y un (objeto, EventArgs) si estaba en un contexto en el que estaba conectando a un tipo base ... –

+0

@Havard S: Eso es posible, pero puede que no siempre sea práctico ... y no olvide que a menudo tenemos que vivir con la API que se nos da.Ciertamente, no voy a reescribir la totalidad de WinForms solo para evitar un elenco ocasional ... –

+0

Por supuesto, dado el legado, el downcasting es práctico, pero sin herencia, usted podría evitarlo para el caso del evento dado un suficiente tipo de sistema –

3

Nunca es una solución ideal y debe evitarse siempre que sea posible, a menos que la alternativa sea peor. A veces, no se puede evitar, p. pre-Generics La biblioteca API estándar de Java tenía muchas clases (la más destacada de las colecciones) que requerían downcasting para ser útil. Y a veces, cambiar el diseño para evitar el abatimiento lo complicaría significativamente, de modo que el abatimiento es la mejor solución.

1

Un ejemplo de downcasting "legal" es Java pre 5.0, donde tuvo que bajar los elementos del contenedor a su tipo concreto al acceder a ellos. Fue inevitable en ese contexto. Sin embargo, esto también muestra el otro lado de la cuestión: si necesita disminuir un poco en una situación dada, comienza a ser malo, por lo que es mejor encontrar otra solución sin descargarlo. Eso resultó en la introducción de genéricos en Java 5.

John Vlissides analiza este problema (también conocido como "Tipo de lavado") en su excelente libro Pattern Hatching (prácticamente una secuela de Design Patterns).

+0

Buen libro de referencia, gracias. Ese es otro aspecto de la pregunta, realmente: ¿es posible dar una medida general para cuando el downcasting es/"comienza a ser" malvado? –

+0

@ Håvard Me temo que no hay una medida objetiva para esto. Jon da buenos ejemplos, que IMO podría resumirse como esta regla general: si los downcasts están localizados en una pequeña porción de tu código y puedes estar seguro de que siempre tienen éxito, entonces están bien. Si los downcasts se extienden sobre el código y/o existe la posibilidad de que se produzcan fallas, entonces son malos. –

+0

Bueno, de ahí el llamado para un mínimo de "consentimiento común". Buen resumen –

Cuestiones relacionadas