14 votes

Puis-je cloner en profondeur un objet C# non étiqueté ICloneable ou Serializable?

J'ai un objet non écrit par moi que j'ai besoin de cloner en mémoire. L'objet n'est pas étiqueté ICloneable ou Serializable donc le clonage profond à travers l'interface ou la sérialisation ne fonctionnera pas. Y a-t-il un moyen de cloner profondément cet objet ? Peut-être un appel API Win32 non sécurisé ?

9voto

JoshBerke Points 34238

Pour information, les interfaces marquées comme ICloneable ne sont pas nécessairement copiées en profondeur. Il revient à l'implémenteur d'implémenter ICloneable et il n'y a aucune garantie qu'il l'aura cloné.

Vous dites que l'objet n'implémente pas ISerializable mais a-t-il l'attribut Serializable?

Créer une copie profonde via une sérialisation binaire est probablement l'une des méthodes les plus simples que je connaisse, car vous pouvez cloner n'importe quel graphe complexe en 3-5 lignes de code. Une autre option serait le XmlSerializer si l'objet peut être XmlSerialized (Vous ne spécifiez pas d'attributs pour la sérialisation ou n'implémentez pas d'interfaces cependant, s'il y a une interface IDictionary alors vous êtes coincé).

En dehors de cela, je ne peux pas vraiment penser à autre chose. Si toutes les données sont accessibles publiquement, vous pourriez créer votre propre routine de clonage. Si ce n'est pas le cas, vous pouvez toujours le cloner en utilisant la réflexion pour obtenir et définir les données privées.

2voto

Marc Gravell Points 482669

La partie "profonde" est la plus difficile. Pour une copie superficielle, vous pourriez utiliser la réflexion pour copier les champs (en supposant que aucun d'entre eux ne sont en lecture seule, ce qui est une grosse hypothèse) - mais il serait très difficile de faire fonctionner cela (automatiquement) autrement.

L'autre option est de fournir vous-même le sérialiseur (et de sérialiser pour un clone profond) - un "sérialiseur substitut". Voici un exemple en VB.

0voto

Will Dean Points 25866

Je pense que la seule façon de faire cela est de réfléchir sérieusement pour décomposer l'objet et tous ses membres (qui peuvent eux-mêmes être d'autres objets avec des membres, etc). C'est ce que ferait le sérialiseur du framework, mais il ne le fera que pour les choses qui ont été marquées correctement.

Je ne suis pas sûr qu'une bibliothèque de réflexion de qualité industrielle comme Mono.Cecil puisse avoir des éléments qui vous aideront.

Je doute que vous trouviez une solution générale robuste (par exemple, il pourrait être difficile de traiter correctement les membres statiques), mais vous pourriez faire fonctionner quelque chose dans un cas spécifique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X