web-dev-qa-db-fra.com

Comment faire une copie d'un objet en c #

Disons que j'ai un cours:

class obj
{
  int a;
  int b;
}

et puis j'ai ce code:

obj myobj = new obj(){ a=1, b=2}
obj myobj2 = myobj;

Maintenant, le code ci-dessus fait référence au premier obj. Ce que je veux, c'est que myobj2 fait référence à une copie du myobj avec les modifications non reflétées dans l’original. J'ai cherché SO et les solutions semblent jusqu'à présent compliquées. Existe-t-il un moyen plus simple de procéder? J'utilise .net 4.5

35
Win Coder

Les propriétés de votre objet sont des types de valeur et vous pouvez utiliser la copie superficielle dans une telle situation:

obj myobj2 = (obj)myobj.MemberwiseClone();

Mais dans d'autres situations, comme si l'un des membres est un type de référence, vous avez besoin de Deep Copy. Vous pouvez obtenir une copie complète d'un objet en utilisant les techniques Serialization et Deserialization à l'aide de BinaryFormatter class:

public static T DeepCopy<T>(T other)
{
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Context = new StreamingContext(StreamingContextStates.Clone);
        formatter.Serialize(ms, other);
        ms.Position = 0;
        return (T)formatter.Deserialize(ms);
    }
}

Le but de la définition de StreamingContext: nous pouvons introduire une logique spéciale de sérialisation et de désérialisation dans notre code à l'aide de l'implémentation de l'interface ISerializable ou de l'utilisation d'attributs intégrés tels que OnDeserialized, OnDeserializing, OnSerializing, OnSerialized. Dans tous les cas, StreamingContext sera passé en tant qu'argument aux méthodes (et au constructeur spécial dans le cas de l'interface ISerializable.). Avec la définition de ContextState sur Clone, nous ne faisons que donner un indice à cette méthode sur le but de la sérialisation.

Informations supplémentaires: (vous pouvez également lire cet article à partir de MSDN )

Une copie superficielle consiste à créer un nouvel objet, puis à copier les champs non statiques de l'objet actuel dans le nouvel objet. Si un champ est un type de valeur, une copie bit par bit du champ est effectuée; pour un type de référence, la référence est copiée mais l'objet référencé ne l'est pas; Par conséquent, l'objet d'origine et son clone font référence au même objet.

Deep Copy crée un nouvel objet, puis copie les champs non statiques de l'objet actuel dans le nouvel objet. Si un champ est un type de valeur, une copie bit par bit du champ est effectuée. Si un champ est un type de référence, une nouvelle copie de l'objet référencé est effectuée.

83
Farhad Jabiyev

Vous pouvez utiliser MemberwiseClone

obj myobj2 = (obj)myobj.MemberwiseClone();

La copie est une copie superficielle, ce qui signifie que les propriétés de référence du clone pointent sur les mêmes valeurs que l'objet d'origine, mais cela ne devrait pas poser de problème dans votre cas, car les propriétés dans obj sont de type valeur.

Si vous possédez le code source, vous pouvez également implémenter ICloneable

4
vc 74