Perché dovrei implementare ICloneable in c#?
-
22-08-2019 - |
Domanda
Mi puoi spiegare perché dovrei ereditare da ICloneable
e implementare la Clone()
metodo?
Se voglio fare una copia profonda, non posso implementare il mio metodo?Diciamo MyClone()
?
Perché dovrei ereditare da ICloneable
?Quali sono i vantaggi?È solo una questione di rendere il codice "più leggibile"?
Soluzione
Non dovresti. Microsoft sconsiglia attuazione ICloneable
perché non c'è alcuna chiara indicazione dall'interfaccia se il metodo di Clone
esegue una o clone di "profondo" "superficiale".
questo post del blog di Brad Abrams indietro nel 2003 (!) per ulteriori informazioni.
Altri suggerimenti
Il ICloneable
interfaccia di per sé non è molto utile, che è quello di dire che non ci sono davvero molte le situazioni in cui è utile sapere che un oggetto è clonabile senza sapere nulla a proposito.Questa è una situazione molto diversa da es. IEnumerable
o IDisposable
;ci sono molte situazioni in cui è utile ad accettare un IEnumerable
senza sapere nulla di diverso da come si enumerano.
D'altra parte, ICloneable
può essere utile quando applicato come un vincolo generico, insieme ad altri vincoli.Per esempio, una classe di base potrebbe utilmente supportare un certo numero di derivati, alcuni dei quali potrebbero essere utilmente clonato, e alcune delle quali potrebbero non.Se il tipo di base esposto un pubblico di clonazione interfaccia, quindi qualsiasi tipologia derivati che non poteva essere clonato, violerebbe il Liskov Principio di Sostituzione.Il modo per evitare questo problema è quello di avere la base di supporto per il tipo di clonazione mediante un metodo Protetto, e consentire tipi derivati per implementare un pubblico di clonazione interfaccia come si vede in forma.
Una volta che è stato compiuto, di un metodo che si vuole accettare un oggetto di un WonderfulBase
tipo, e deve essere in grado di clonare, potrebbe essere codificata accettare un WonderfulBase oggetto che supporta la clonazione (utilizzando un parametro di tipo generico con base di tipo e ICloneable
vincoli).Anche se il ICloneable
interfaccia di non indicare profondo o superficiale clonazione, la documentazione per WonderfulBase
indica se è clonabile WonderfulBase
dovrebbe essere profondo o superficiale-clonato.Essenzialmente, il ICloneable
interfaccia di non fare nulla che non sia effettuata mediante la definizione di ICloneableWonderfulBase
, tranne che vorresti evitare di dover definire nomi diversi per ogni diverso è clonabile classe base.
ICloneable
è uno di quei manufatti nel BCL, che è stata controversa. Non v'è alcun motivo reale IMHO per la sua attuazione. Detto questo, se ho intenzione di creare un metodo clone poi faccio implementare ICloneable
, e fornisco la mia versione dattiloscritta forte di Clone
.
Il problema con ICloneable
viene mai indicato se Clone
era un superficiale o una copia profonda, che sono cose molto diverse. Il fatto che non v'è alcuna ICloneable<T>
potrebbe essere un'indicazione sul pensiero di Microsoft su ICloneable
Matt è corretto, non ne fanno uso. Crea il tuo metodo di Copy()
(o nome simile) e renderlo perfettamente chiaro nella vostra API pubblica se il metodo è la creazione di una copia profonda o superficiale del vostro oggetto.