11
votes

.NET CLONING DE PROFESSION - Quel est le meilleur moyen de le faire?

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 n'est pas assez bon.


3 commentaires

Ê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


7 Réponses :


0
votes

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.


1 commentaires

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.



15
votes

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 absolument la performance la plus rapide, puis la sérialisation est souvent la réponse la plus gérable.

Ceci est l'un des cas où binarinformatter 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.

Si vous le souhaitez un peu plus vite (mais sans votre propre code), alors protocoudf-net 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).

Autres sérialiseurs ( xmlSerializer , DatacontractSerializer ) va aussi bien, mais s'il est juste pour clone, ils peuvent ne pas offrir beaucoup sur < Code> BinaryFormatter (sauf peut-être que xmlSerializer n'a pas besoin [sérialisable] . .

Donc vraiment, cela dépend de vos classes exactes et du scénario.


1 commentaires

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.



0
votes

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.


0 commentaires

5
votes

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));
    }


0 commentaires

10
votes

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);
    }
}


1 commentaires

Ne fonctionne pas lorsque certaines propriétés de l'objet cloné sont des interfaces (par exemple, iEnumerable, ilist, etc.). Jette une exception.



1
votes

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


0 commentaires

0
votes

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>).

Au fait, BinaryFormatter est très lent pour cette tâche et peut être bon uniquement pour les tests.


0 commentaires