Perché dovrei implementare ICloneable in c #?


111

Puoi spiegarmi perché dovrei ereditare ICloneablee implementare il Clone()metodo?

Se voglio fare una copia completa, non posso semplicemente implementare il mio metodo? Diciamo MyClone()?

Perché dovrei ereditare da ICloneable? Quali sono i vantaggi? Si tratta solo di rendere il codice "più leggibile"?


Risposte:



29

L' ICloneableinterfaccia di per sé non è molto utile, vale a dire che non ci sono davvero molte situazioni in cui è utile sapere che un oggetto è clonabile senza sapere altro al riguardo. Questa è una situazione molto diversa da es. IEnumerableO IDisposable; ci sono molte situazioni in cui è utile accettare un IEnumerablesenza sapere altro che come enumerarlo.

D'altra parte, ICloneablepuò essere utile se applicato come vincolo generico insieme ad altri vincoli. Ad esempio, una classe base potrebbe supportare utilmente un numero di derivati, alcuni dei quali potrebbero essere utilmente clonati e altri no. Se il tipo di base stesso esponeva un'interfaccia di clonazione pubblica, qualsiasi tipo derivato che non poteva essere clonato violerebbe il principio di sostituzione di Liskov. Il modo per evitare questo problema consiste nel fare in modo che il tipo di base supporti la clonazione utilizzando un metodo protetto e consentire ai tipi derivati ​​di implementare un'interfaccia di clonazione pubblica come meglio credono.

Una volta ottenuto ciò, un metodo che vuole accettare un oggetto di un WonderfulBasetipo e deve essere in grado di clonarlo, potrebbe essere codificato per accettare un oggetto WonderfulBase che supporta la clonazione (utilizzando un parametro di tipo generico con tipo di base e ICloneablevincoli) . Sebbene l' ICloneableinterfaccia stessa non indichi la clonazione profonda o superficiale, la documentazione per WonderfulBaseindicherebbe se clonabile WonderfulBasedovrebbe essere clonata in profondità o in profondità. In sostanza, l' ICloneableinterfaccia non realizzerebbe nulla che non sarebbe ottenuto definendo ICloneableWonderfulBase, tranne per il fatto che eviterebbe di dover definire nomi diversi per ogni diversa classe base clonabile.


18

ICloneableè uno di quegli artefatti nella BCL che è stato controverso. Non c'è alcun motivo reale IMHO per implementarlo. Detto questo, se creo un metodo clone, lo implemento ICloneablee fornisco la mia versione fortemente tipizzata di Clone.

Il problema ICloneablenon è mai stato indicato se Clonefosse una copia superficiale o profonda che sono cose molto diverse. Il fatto che non ci sia ICloneable<T>potrebbe essere un'indicazione sui pensieri di Microsoft su ICloneable


9

Matt ha ragione, non usarlo. Crea il tuo Copy()metodo (o un nome simile) e chiarisci perfettamente nella tua API pubblica se il tuo metodo sta creando una copia profonda o superficiale del tuo oggetto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.