Clone de la classe dérivée de la classe de base de la méthode
J'ai une classe de base abstraite Base
qui a certaines propriétés communes, et de nombreux dérivés de ceux qui mettent en œuvre des logiques différentes, mais rarement, des champs supplémentaires.
public abstract Base
{
protected int field1;
protected int field2;
....
protected Base() { ... }
}
Parfois j'ai besoin de clone de la classe dérivée. Donc, je pense, suffit de faire un virtuel Clone
méthode dans ma classe de base et remplacez uniquement dans les classes dérivées qui ont des champs supplémentaires, mais bien sûr, ma Base
classe ne serait pas plus abstrait (ce qui n'est pas un problème puisqu'il ne dispose que d'un protected
constructeur).
public Base
{
protected int field1;
protected int field2;
....
protected Base() { ... }
public virtual Base Clone() { return new Base(); }
}
public A : Base { }
public B : Base { }
-
La chose est, depuis je ne peux pas savoir le type de la classe dérivée dans ma la Base de l'un, ne serait-ce pas conduire à avoir un
Base
instance de classe, même si je l'appelle sur les dérivées de celles ? (a.Clone();
) (en fait, après un test c'est ce qui se passe, mais peut-être que mon test n'a pas été bien conçu c'est pourquoi j'ai un doute à ce sujet) -
Est-il un bon moyen (pattern) de mettre en œuvre une base de
Clone
méthode de travail que je pense ou ce que je dois écrire le même code dans chaque classe dérivée (j'aimerais vraiment éviter ça...)
Merci pour votre aide
- Pourquoi ne pas simplement faire la
Clone
méthode abstraite, de sorte qu'il doit être mis en œuvre par les classes dérivées? - c'est ce que j'ai fait à l'origine, mais il m'entrainer à l'écriture de code en double. Presque tout ce qui pourrait être fait dans la base de méthode clone, c'est pourquoi
- Pourquoi ne pas utiliser
this.MemberwiseClone()
? - parce que je fais quelques modifications dans les champs pendant le processus de clonage, ce n'est pas exactement un clone, mais à proximité de est. Mais cela pourrait être une option de toute façon depuis que j'ai appeler cette méthode de clonage seulement dans 1 endroit, il aurait juste été mieux de mettre en œuvre cette logique dans la classe de base
- Qui fait sens, vérifier mon ansewer, et Alexander Simonov a également la bonne réponse ainsi
- En effet, les deux sont de bonnes réponses, merci pour votre aide!
Vous devez vous connecter pour publier un commentaire.
Juste remplacer le
Clone
et avez une autre méthode pourCreateInstance
ensuite faire vos choses.Cette façon, vous pourriez avoir seulement
Base
classe en évitant les génériques.Clone()
une seule fois dans la classe de base, et tout ce qu'il fait, c'est appeler un virtuelCloneImpl()
. La classe de base deCloneImpl()
mise en œuvre n'effectue deMemberwiseCopy()
qui construit un exemplaire de ce type est en fait l'appel. Tous les dérivésCloneImpl()
s (dans un multi-niveaux hiérarchie d'héritage) premier appelbase.CloneImpl()
à effectuer tout au fond de la copie de tous les membres de classe de base, et ensuite faire face à leurs propres membres qui ont besoin d'copie en profondeur sémantique.Vous pouvez ajouter un constructeur de copie pour votre classe de base:
Clone()
méthode. VoirChild3
classe, j'ai mis à jour ma réponse.Vous pourriez faire quelque chose comme ceci:
Mais je doute que ça va apporter quelque chose d'utile. Je vais créer un autre exemple..
J'ai fait quelque chose de similaire comme Alexandre Simonov, mais peut-être plus simple. L'idée est (comme je l'ai dit dans un commentaire) pour avoir juste un
Clone()
dans la classe de base et de laisser tout le travail virtuelCloneImpl()
qui chaque classe définit en tant que de besoin, en s'appuyant sur laCloneImpl()
s des classes de base.Création d'un type approprié est laissé de C#
MemberwiseClone()
qui va faire ce qu'il faut pour l'objet qui appelle. Cela permet également d'éviter la nécessité d'un constructeur par défaut dans toutes les classes (aucun n'est jamais appelé).De sortie:
J'ai eu une autre idée à l'aide de la classe Activator:
Mais je pencherais pour le Alexander Simonov réponse.
Si la performance n'est pas important pour votre cas, vous pouvez simplifier votre code en créant simplement une méthode clone qui peut cloner que ce soit pour quoi que si les propriétés sont les mêmes:
Trouve cette question, tout en essayant de résoudre ce problème exact, a eu un peu de plaisir avec LINQPad tout en elle.
La preuve de concept: