Pouvez-vous m'expliquer pourquoi je devrais hériter ICloneable
et implémenter la Clone()
méthode?
Si je veux faire une copie complète, ne puis-je pas simplement implémenter ma méthode? Disons MyClone()
?
Pourquoi devrais-je hériter ICloneable
? Quels sont les avantages? S'agit-il simplement de rendre le code "plus lisible"?
c#
.net
cloneable
icloneable
uinc
la source
la source
Réponses:
Tu ne devrais pas. Microsoft recommande de ne pas l'implémenter
ICloneable
car il n'y a aucune indication claire de l'interface si votreClone
méthode effectue un clone "profond" ou "superficiel".Voir ce billet de blog de Brad Abrams en 2003 (!) Pour plus d'informations.
la source
L'
ICloneable
interface en elle - même n'est pas très utile, c'est-à-dire qu'il n'y a vraiment pas beaucoup de situations où il est utile de savoir qu'un objet est clonable sans rien savoir d'autre à son sujet. C'est une situation très différente de par exempleIEnumerable
ouIDisposable
; il existe de nombreuses situations où il est utile d'accepter unIEnumerable
sans rien savoir d'autre que de l'énumérer.D'un autre côté, cela
ICloneable
peut être utile lorsqu'il est appliqué en tant que contrainte générique avec d'autres contraintes. Par exemple, une classe de base pourrait utilement prendre en charge un certain nombre de dérivés, dont certains pourraient être utilement clonés et d'autres pas. Si le type de base lui-même exposait une interface de clonage publique, alors tout type dérivé qui ne pourrait pas être cloné violerait le principe de substitution de Liskov. Le moyen d'éviter ce problème consiste à faire en sorte que le type de base prenne en charge le clonage à l'aide d'une méthode Protected et autorise les types dérivés à implémenter une interface de clonage publique comme ils l'entendent.Une fois que cela a été accompli, une méthode qui veut accepter un objet d'un
WonderfulBase
type, et doit pouvoir le cloner, pourrait être codée pour accepter un objet WonderfulBase qui prend en charge le clonage (en utilisant un paramètre de type générique avec un type de base et desICloneable
contraintes) . Bien que l'ICloneable
interface n'indique pas elle-même un clonage profond ou superficiel, la documentation pourWonderfulBase
indiquerait si le clonageWonderfulBase
doit être cloné profond ou superficiel. Essentiellement, l'ICloneable
interface n'accomplirait rien qui ne serait pas accompli en définissantICloneableWonderfulBase
, sauf qu'elle éviterait d'avoir à définir des noms différents pour chaque classe de base clonable différente.la source
ICloneable
est l'un de ces artefacts de la BCL qui a été controversé. Il n'y a aucune vraie raison IMHO de le mettre en œuvre. Cela dit, si je vais créer une méthode de clonage, je l'implémenteICloneable
et je fournis ma propre version typée forte deClone
.Le problème avec
ICloneable
est qu'il n'a jamais indiqué s'ilClone
s'agissait d'une copie superficielle ou profonde qui sont des choses très différentes. Le fait qu'il n'y ait aucuneICloneable<T>
indication sur les réflexions de Microsoft sur ICloneablela source
Matt a raison, ne l'utilisez pas. Créez votre propre
Copy()
méthode (ou un nom similaire) et indiquez clairement dans votre API publique si votre méthode crée une copie profonde ou superficielle de votre objet.la source