En C #, ¿cuál es la forma preferida de agregar funcionalidad de copia (profunda) a una clase? ¿Debería uno implementar el constructor de copia, o más bien derivar de ICloneable e implementar el método Clone ()?
El problema con ICloneablees, como han mencionado otros, que no especifica si se trata de una copia profunda o superficial, lo que la hace prácticamente inutilizable y, en la práctica, poco utilizada. También vuelve object, lo cual es un fastidio, ya que requiere mucho yeso. (Y aunque mencionaste específicamente las clases en la pregunta, implementar ICloneableen un structrequiere boxeo).
Un constructor de copias también sufre uno de los problemas con ICloneable. No es obvio si un constructor de copias está haciendo una copia profunda o superficial.
Account clonedAccount = new Account(currentAccount); // Deep or shallow?
Lo mejor sería crear un método DeepClone (). De esta manera la intención es perfectamente clara.
Esto plantea la cuestión de si debería ser un método estático o de instancia.
Account clonedAccount = currentAccount.DeepClone(); // instance method
o
Account clonedAccount = Account.DeepClone(currentAccount); // static method
A veces prefiero un poco la versión estática, solo porque la clonación parece algo que se está haciendo en un objeto en lugar de algo que el objeto está haciendo. En cualquier caso, habrá problemas con los que lidiar al clonar objetos que son parte de una jerarquía de herencia, y cómo esos problemas pueden finalmente impulsar el diseño.
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();
}
}