2010-02-14 12 views
5

Qual è la tua prospettiva sul downcasting? È SEMPRE sbagliato, o ci sono casi in cui è accettabile, o addirittura preferibile o desiderato?È downcasting (cioè casting per tipo derivato) SEMPRE sbagliato?

C'è qualche buona misura/linea guida che possiamo dare che ci dice quando downcasting è "cattivo", e quando è "ok"/"buono"?

(lo so a similar question exists, ma quella domanda gira fuori da un caso concreto. Mi piacerebbe avere ha risposto da una prospettiva generale di progettazione.)

+2

niente è __ALWAYS__ sbagliato, beh eccetto gotos e ottimizzazione prematura senza profilazione prima. :-) –

+0

Giusto, forse avrei dovuto riformulare la mia intestazione. ;) Stavo cercando (preferibilmente un insieme di) casi in cui sarebbe "buono"/"cattivo". –

+1

Se il gotos è così sbagliato, perché Java usa i salti lunghi per le sue eccezioni? Anche le affermazioni che sono abusate di più hanno il loro scopo ... – Scharrels

risposta

8

No, non è sicuramente sempre sbagliato.

Ad esempio, supponiamo che in C# sia presente un gestore di eventi, a cui viene assegnato un parametro sender, che rappresenta il mittente dell'evento. Ora puoi collegare il gestore di eventi a diversi pulsanti, ma sai che sono sempre pulsanti. È ragionevole trasmettere sender a Button all'interno di tale codice.

Questo è solo un esempio: ce ne sono molti altri. A volte è solo un modo per aggirare un'API leggermente imbarazzante, altre volte esce dal non essere in grado di esprimere in modo pulito il tipo all'interno del normale sistema di tipi. Ad esempio, potresti avere un valore incapsulato appropriato per Dictionary<Type, object>, con metodi generici per aggiungere e recuperare valori, in cui il valore di una voce è del tipo di chiave. Un cast è del tutto naturale qui - puoi vedere che funzionerà sempre, e sta dando più sicurezza al resto del sistema.

+0

Vero, Jon, ma il caso degli eventi C# non è stato (almeno in parte) evitato con l'introduzione di tipi di co/contro-varianti? Potresti collegarti ad es. un gestore (Button, ButtonEventArgs) se si stava agganciare a un pulsante e un oggetto (oggetto, EventArgs) se si trovava in un contesto in cui si stava agganciata a un tipo di base ... –

+0

@Havard S: È possibile, ma potrebbe non essere sempre pratico ... e non dimenticare che spesso dobbiamo vivere con l'API che ci viene data.Non sto certamente riscrivendo l'intera WinForms solo per evitare un cast occasionale ... –

+0

Ovviamente, data l'eredità, il downcasting è pratico, ma senza legacy si potrebbe evitarlo per il caso dell'evento dato un sufficiente sistema di tipo. –

3

Non è mai una soluzione ideale e dovrebbe essere evitato laddove possibile, a meno che l'alternativa non sia peggio. A volte, non può essere evitato, ad es. pre-Generics La libreria API standard di Java aveva molte classi (in particolare le raccolte) che richiedevano il downcasting per essere utili. E a volte, cambiare il design per evitare il downcast lo complicherebbe in modo significativo, così che il downcast è la soluzione migliore.

1

Un esempio di downcasting "legale" è Java pre 5.0 in cui è necessario abbattere gli elementi del contenitore nel loro tipo concreto durante l'accesso. Era inevitabile in quel contesto. Questo mostra anche l'altro aspetto della domanda: se hai bisogno di downcast molto in una determinata situazione, inizia a essere malvagio, quindi è meglio trovare un'altra soluzione senza downcasting. Che ha portato alla introduzione dei generici in Java 5.

John Vlissides analizza questo problema (alias "Type in materia di riciclaggio") molto nel suo eccellente libro Pattern Hatching (praticamente un sequel di Design Patterns).

+0

Buon riferimento al libro, grazie. Questo è un altro aspetto della domanda, in realtà: è possibile dare una misura generale per quando il downcasting è/"inizia a diventare" cattivo? –

+0

@ Håvard temo che non ci sia alcuna misura oggettiva per questo. Jon fornisce dei buoni esempi, che IMO potrebbe riassumere come questa regola: se i downcast sono localizzati in una piccola parte del codice e si può essere certi che hanno sempre successo, allora sono OK. Se i downcast sono distribuiti sul codice e/o c'è una possibilità di errori di casting, allora sono cattivi. –

+0

Bene, da qui la richiesta di un minimo "consenso comune". Buon riassunto –

Problemi correlati