Duplicate possible:
Comment faire une copie profonde d'un objet en .Net (C # en particulier)?
Veuillez consulter le code ci-dessous (extrait d'un livre C #):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
Je comprends que cela produit le résultat ci-dessous:
objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40
Les deux dernières lignes de la sortie ne me posent pas de problème, mais les deux premières me disent que objectA
et objectB
pointent vers le même bloc de mémoire (car en C #, les objets sont des types de référence).
La question est de savoir comment créer objectB
, une copie de objectA
de sorte qu’elle pointe vers une zone différente de la mémoire. Je comprends qu’essayer d’affecter leurs membres peut ne pas marcher puisque ces membres peuvent aussi être des références. Alors, comment puis-je créer objectB
une entité complètement différente de objectA
?
Merci
Il n'y a pas de manière intégrée. Vous pouvez demander à MyClass d'implémenter l'interface IClonable
(mais c'est en quelque sorte déconseillé) ou tout simplement d'écrire votre propre méthode Copy/Clone. Dans les deux cas, vous devrez écrire du code.
Pour les gros objets, vous pouvez envisager la sérialisation et la désérialisation (via un MemoryStream), juste pour réutiliser le code existant.
Quelle que soit la méthode, réfléchissez bien à ce que "copie" signifie exactement. À quelle profondeur doit-il aller, y a-t-il des champs Id à exclure, etc.
Vous pourriez faire:
class myClass : ICloneable
{
public String test;
public object Clone()
{
return this.MemberwiseClone();
}
}
alors vous pouvez faire
myClass a = new myClass();
myClass b = (myClass)a.Clone();
N.B. MemberwiseClone()
Crée une copie superficielle du System.Object actuel.
Le moyen le plus simple consiste à écrire un constructeur de copie dans la classe MyClass.
Quelque chose comme ça:
namespace Example
{
class MyClass
{
public int val;
public MyClass()
{
}
public MyClass(MyClass other)
{
val = other.val;
}
}
}
Le second constructeur accepte simplement un paramètre de son propre type (celui que vous voulez copier) et crée un nouvel objet assigné avec la même valeur
class Program
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = new MyClass(objectA);
objectA.val = 10;
objectB.val = 20;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.ReadKey();
}
}
sortie:
objectA.val = 10
objectB.val = 20
Il y a déjà une question à ce sujet, vous pourriez peut-être la lire
Il n'y a pas de méthode Clone () telle qu'elle existe dans Java par exemple, mais vous pouvez inclure un constructeur de copie dans vos classements, c'est une autre bonne approche.
class A
{
private int attr
public int Attr
{
get { return attr; }
set { attr = value }
}
public A()
{
}
public A(A p)
{
this.attr = p.Attr;
}
}
Ce serait un exemple, en copiant le membre 'Attr' lors de la construction du nouvel objet.