In C #, qual è il modo preferito per aggiungere funzionalità di copia (approfondita) a una classe? Si dovrebbe implementare il costruttore di copia, o piuttosto derivare da ICloneable e implementare il metodo Clone ()?
Il problema con ICloneableè, come altri hanno detto, che non specifica se si tratta di una copia profonda o superficiale, il che la rende praticamente inutilizzabile e, in pratica, usata raramente. Inoltre ritorna object, il che è un dolore, poiché richiede molto lancio. (E sebbene tu abbia menzionato specificamente le classi nella domanda, l'implementazione ICloneablesu un structrichiede boxe.)
Un copy constuctor soffre anche di uno dei problemi con ICloneable. Non è ovvio se un costruttore di copie sta eseguendo una copia profonda o superficiale.
Account clonedAccount = new Account(currentAccount); // Deep or shallow?
Sarebbe meglio creare un metodo DeepClone (). In questo modo l'intento è perfettamente chiaro.
Ciò solleva la questione se debba essere un metodo statico o di istanza.
Account clonedAccount = currentAccount.DeepClone(); // instance method
o
Account clonedAccount = Account.DeepClone(currentAccount); // static method
A volte preferisco leggermente la versione statica, solo perché la clonazione sembra qualcosa che viene fatto su un oggetto piuttosto che qualcosa che sta facendo l'oggetto. In entrambi i casi, ci saranno problemi da affrontare durante la clonazione di oggetti che fanno parte di una gerarchia di ereditarietà e il modo in cui tali problemi vengono risolti potrebbe alla fine guidare il progetto.
class CheckingAccount : Account
{
CheckAuthorizationScheme checkAuthorizationScheme;
public override Account DeepClone()
{
CheckingAccount clone = new CheckingAccount();
DeepCloneFields(clone);
return clone;
}
protected override void DeepCloneFields(Account clone)
{
base.DeepCloneFields(clone);
((CheckingAccount)clone).checkAuthorizationScheme = this.checkAuthorizationScheme.DeepClone();
}
}