Je dois effectuer un clonage profond sur mon modèle d'objet complexe. Selon vous, quelle est la meilleure façon de le faire dans .net?
J'ai pensé à sérialiser / désérialiser
Pas besoin de mentionner que Memberwiseclone code> n'est pas assez bon. p>
7 Réponses :
Le meilleur moyen est probablement de mettre en œuvre l'interface système.iclonable dans votre objet et tous ses champs qui nécessitent également des capacités de clonage de profondes personnalisées. Ensuite, vous implémentez le Méthode de clone pour retourner une profonde Copie de votre objet et de ses membres. P>
Il y a encore des recommandations contre cela, et je suis d'accord avec eux. ICLONABLE sur un objet peut signifier de profondeur, tandis que sur un autre, il est peu profond. Il n'y a aucun moyen de discerner lors de la prise d'appel. Bien sûr, cela n'est vraiment pas complètement applicable à un projet interne, mais n'est pas une mauvaise pratique de reconnaître tôt.
Si vous contrôlez le modèle d'objet, vous pouvez écrire du code pour le faire, mais c'est beaucoup de maintenance. Cependant, il y a beaucoup de problèmes, ce qui signifie que si vous avez besoin Ceci est l'un des cas où Si vous le souhaitez un peu plus vite (mais sans votre propre code), alors Autres sérialiseurs ( Donc vraiment, cela dépend de vos classes exactes et du scénario. P> binarinformatter code> fonctionne de manière acceptable; Normalement, je ne suis pas un fan (en raison des problèmes avec les versions, etc.) - mais depuis que les données sérialisées concernent une consommation immédiate, ce n'est pas un problème. P>
protocoudf-net code> peut aider, mais nécessite des modifications de code (pour ajouter les métadonnées nécessaires (pour ajouter les métadonnées nécessaires). Et il est basé sur des arbres (non graphique). P>
xmlSerializer code>,
DatacontractSerializer code>) va aussi bien, mais s'il est juste em> pour clone, ils peuvent ne pas offrir beaucoup sur < Code> BinaryFormatter code> (sauf peut-être que
xmlSerializer code> n'a pas besoin
[sérialisable] code>. P>.
Peut-être qu'un lien peut être gentil. J'utilise UWP et je ne peux pas utiliser Binarinformatter. Le sérialisateur XML est donné ci-dessous par Marty. Je suis curieux de DatacontractSérialiseur et de Protobuf-Net.
Vous pouvez essayer Altserialize qui dans de nombreux cas est plus rapide que le. Sérialisateur net. Il fournit également des attributs de mise en cache et personnalisés pour accélérer la sérialisation. P>
Exemple de clonage profond du magazine MSDN:
Object DeepClone(Object original) { // Construct a temporary memory stream MemoryStream stream = new MemoryStream(); // Construct a serialization formatter that does all the hard work BinaryFormatter formatter = new BinaryFormatter(); // This line is explained in the "Streaming Contexts" section formatter.Context = new StreamingContext(StreamingContextStates.Clone); // Serialize the object graph into the memory stream formatter.Serialize(stream, original); // Seek back to the start of the memory stream before deserializing stream.Position = 0; // Deserialize the graph into a new set of objects // and return the root of the graph (deep copy) to the caller return (formatter.Deserialize(stream)); }
Si vous exécutez un code dans un environnement de fiducie partiel tel que le cloud rackspace, vous serez probablement limité à utiliser le Binaryformater. Le XMLSerializer peut être utilisé à la place.
public static T DeepClone<T>(T obj) { using (var ms = new MemoryStream()) { XmlSerializer xs = new XmlSerializer(typeof(T)); xs.Serialize(ms, obj); ms.Position = 0; return (T)xs.Deserialize(ms); } }
Ne fonctionne pas lorsque certaines propriétés de l'objet cloné sont des interfaces (par exemple, iEnumerable, ilist, etc.). Jette une exception.
Veuillez jeter un oeil à l'article vraiment bon article clone d'objet C # Wars . J'ai trouvé une solution très intéressante là-bas: Copée: un cadre de copie ou de clonage Objets .NET P>
meilleur moyen de la mettre en œuvre manuellement. Ce sera vraiment plus rapide que toute autre méthode générique. De plus, il y a beaucoup de bibliothèques pour cette opération (vous pouvez voir une liste avec des performances de référence ici < / a>). p>
Au fait, BinaryFormatter est très lent pour cette tâche et peut être bon uniquement pour les tests. P>
Être vraiment prudent; Est-ce ce que tu veux vraiment dire? Les références circulaires entre les objets peuvent rapidement causer des problèmes avec un clonage profond.
Cela le fait sans sérialisation ValueInject.CodePlex.com/.../a>
Ultramapper Nuget.org/packages/ultramapper