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é ?
Réponses
Trop de publicités?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.
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.
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.