Maison >développement back-end >Tutoriel C#.Net >Analyse d'exemples de copie superficielle et de copie profonde C#

Analyse d'exemples de copie superficielle et de copie profonde C#

高洛峰
高洛峰original
2017-01-19 11:41:501616parcourir

Dans certains cas, nous devons lire les données de la base de données pour remplir l'objet ou lire le fichier du disque dur pour remplir l'objet, mais cela prend relativement du temps. A cette époque, nous pensons à copier des objets. Cet article analyse l'utilisation de la copie superficielle et de la copie profonde C# sous forme d'exemples. Les détails sont les suivants :

1. Copie superficielle

1. Qu'est-ce qu'une "copie superficielle" :

Lors de la copie d'un objet à l'avance, pour les membres de type valeur de l'objet, se copiera, pour les membres de type référence de l'objet, copiera uniquement la référence de l'objet, cette référence pointe vers l'instance de l'objet sur le tas géré.

2. Il existe un objet qui contient des membres de classe de type référence et des membres de structure de type valeur

Cinema contient un membre de type référence Room et un membre de type valeur Film.

public class Room
{
  public int _maxSeat;
 
  public Room(int maxSeat)
  {
    this._maxSeat = maxSeat;
  }
}
 
public struct Film
{
  public string _name;
 
  public Film(string name)
  {
    this._name = name;
  }
}
 
public class Cinema
{
  public Room _room;
  public Film _film;
 
  public Cinema(Room room, Film film)
  {
    this._room = room;
    this._film = film;
  }
 
  public object Clone()
  {
    return MemberwiseClone(); //对引用类型实施浅复制
  }
}

3. Testez l'effet après la copie

① Imprimez les valeurs des membres de type valeur et de type référence de l'objet d'origine avant de copier
② Pour la copie de l'objet d'origine, imprimez les valeurs des membres de type valeur et de type référence de l'objet copié
③ Modifiez la valeur de l'objet d'origine, imprimez les membres de type valeur et de type référence de l'original objet à nouveau
④ Imprimez à nouveau le type de valeur et le type de référence de l'objet copié Valeur membre

static void Main(string[] args)
{
  Room room1 = new Room(60);
  Film film1 = new Film("家园防线");
  Cinema cinema1 = new Cinema(room1, film1);
  Cinema cinema2 = (Cinema)cinema1.Clone();
  Console.WriteLine("拷贝之前,结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema1._film._name,cinema1._room._maxSeat);
 
  Console.WriteLine("拷贝之后,新的结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema2._film._name, cinema2._room._maxSeat);
 
  //修改拷贝之前引用类型的字段值
  cinema1._film._name = "极品飞车";
  cinema1._room._maxSeat = 80;
 
  Console.WriteLine("修改之后,结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema1._film._name, cinema1._room._maxSeat);
  Console.WriteLine("修改之后,新的结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema2._film._name, cinema2._room._maxSeat);
 
  Console.ReadKey();
}

Analyse :

Le point clé de la copie superficielle est que le type de référence est copié dans la référence d'objet, qui pointe vers l'instance d'objet sur le tas géré. La modification de la valeur du type de référence correspondant d'origine affectera l'objet copié.

2. Copie profonde

1. Qu'est-ce que la "copie profonde"

Copiez l'objet pointé par le membre de référence et attribuez la valeur contenue dans l'instance d'objet d'origine sur les données du tas géré, puis créez une nouvelle instance d'objet sur le tas géré.

2. Copie approfondie en copiant chaque membre d'objet

public object Clone()
{
  Room room = new Room();
  room._maxSeat = this._room._maxSeat;//复制当前引用类型成员的值到新对象
  Film film = this._film; //值类型直接赋值
  Cinema cinema = new Cinema(room, film);
  return cinema;
}

3. La copie approfondie peut également être effectuée par sérialisation et désérialisation

public object Clone1()
{
  BinaryFormatter bf = new BinaryFormatter();
  MemoryStream ms = new MemoryStream();
  bf.Serialize(ms, this); //复制到流中
  ms.Position = 0;
  return (bf.Deserialize(ms));
}

4. Utilisez la copie profonde de sérialisation et de désérialisation, mais toutes les classes doivent être marquées [Sérialisable]. Le code de test est le suivant :

[Serializable]
public class Room
{
  public int _maxSeat;
 
  public Room()
  {}
 
  public Room(int maxSeat)
  {
    this._maxSeat = maxSeat;
  }
}
 
[Serializable]
public struct Film
{
  public string _name;
 
  public Film(string name)
  {
    this._name = name;
  }
}
 
[Serializable]
public class Cinema
{
  public Room _room;
  public Film _film;
 
  public Cinema(Room room, Film film)
  {
    this._room = room;
    this._film = film;
  }
 
  //浅拷贝
  //public object Clone()
  //{
  //  return MemberwiseClone(); //对引用类型实施浅复制
  //}
 
  //深拷贝 对每个对象成员进行复制
  public object Clone()
  {
    Room room = new Room();
    room._maxSeat = this._room._maxSeat;//复制当前引用类型成员的值到新对象
    Film film = this._film; //值类型直接赋值
    Cinema cinema = new Cinema(room, film);
    return cinema;
  }
 
  //使用序列化和反序列化进行复制
  public object Clone1()
  {
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    bf.Serialize(ms, this); //复制到流中
    ms.Position = 0;
    return (bf.Deserialize(ms));
  }
}

5. Testez l'effet après la copie

① Imprimez les valeurs des membres de type valeur et de type référence de l'objet d'origine avant de copier
② Pour la copie de l'objet d'origine, imprimez le type de valeur et la référence de l'objet copié La valeur du membre de type
③ Changer la valeur de l'objet d'origine et imprimer à nouveau le type de valeur et le membre de type référence de l'objet d'origine
④ Imprimer le type de valeur et le membre de type référence de l'objet copié encore

static void Main(string[] args)
   {
     Room room1 = new Room(60);
     Film film1 = new Film("家园防线");
     Cinema cinema1 = new Cinema(room1, film1);
     Cinema cinema2 = (Cinema)cinema1.Clone1();
     Console.WriteLine("拷贝之前,结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema1._film._name,cinema1._room._maxSeat);
 
     Console.WriteLine("拷贝之后,新的结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema2._film._name, cinema2._room._maxSeat);
 
     //修改拷贝之前引用类型的字段值
     cinema1._film._name = "极品飞车";
     cinema1._room._maxSeat = 80;
 
     Console.WriteLine("修改之后,结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema1._film._name, cinema1._room._maxSeat);
     Console.WriteLine("修改之后,新的结构成员的字段值为{0},引用类型成员的字段值为{1}", cinema2._film._name, cinema2._room._maxSeat);
 
     Console.ReadKey();
   }

Résultat :

Analyse dexemples de copie superficielle et de copie profonde C#

Analyse :

Après copie en profondeur , les membres de référence des deux objets ont été Séparation, la modification de la valeur du membre de type référence de l'objet d'origine n'affectera pas la valeur du membre de type référence de l'objet copié.

Pour plus d'articles liés à l'analyse d'exemples de copie superficielle et de copie profonde C#, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn