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