Heim  >  Artikel  >  Backend-Entwicklung  >  C#-Beispielanalyse für flache Kopien und tiefe Kopien

C#-Beispielanalyse für flache Kopien und tiefe Kopien

高洛峰
高洛峰Original
2017-01-19 11:41:501592Durchsuche

In einigen Fällen müssen wir Daten aus der Datenbank lesen, um das Objekt zu füllen, oder die Datei von der Festplatte lesen, um das Objekt zu füllen, aber das ist relativ zeitaufwändig. Zu diesem Zeitpunkt denken wir an das Kopieren von Objekten. Dieser Artikel analysiert die Verwendung von C# Shallow Copy und Deep Copy anhand von Beispielen. Die Details lauten wie folgt:

1. Flache Kopie

1. Was ist „flache Kopie“:

Beim Vorabkopieren eines Objekts für die Werttypmitglieder von Das Objekt kopiert sich selbst. Für Referenztypmitglieder des Objekts wird nur die Objektreferenz kopiert. Diese Referenz verweist auf die Objektinstanz im verwalteten Heap.

2. Es gibt ein Objekt, das Klassenmitglieder vom Referenztyp und Strukturmitglieder vom Werttyp enthält.

Cinema enthält das Referenztypmitglied Room und das Werttypmitglied 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. Testen Sie den Effekt nach dem Kopieren

① Drucken Sie die Werte der Werttyp- und Referenztypmitglieder des Originalobjekts vor dem Kopieren aus
② Drucken Sie für die Originalobjektkopie die Werte der Werttyp- und Referenztypmitglieder des kopierten Objekts aus.
③ Ändern Sie den Wert des Originalobjekts, drucken Sie die Werttyp- und Referenztypmitglieder des Originals aus Objekt erneut
④ Werttyp und Referenztyp des kopierten Objekts erneut drucken Mitgliedswert

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:

Der Kernpunkt der flachen Kopie ist dass der Referenztyp in die Objektreferenz kopiert wird, die auf die Objektinstanz auf dem verwalteten Heap verweist. Das Ändern des Werts des ursprünglichen entsprechenden Referenztyps wirkt sich auf das kopierte Objekt aus.

2. Deep Copy

1. Was ist „Deep Copy“?

Kopieren Sie das Objekt, auf das das Referenzmitglied zeigt, und weisen Sie den in der ursprünglichen Objektinstanz enthaltenen Wert zu Erstellen Sie die verwalteten Heap-Daten und erstellen Sie dann eine neue Objektinstanz auf dem verwalteten Heap.

2. Tiefenkopie durch Kopieren jedes Objektmitglieds

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. Tiefenkopie kann auch durch Serialisierung und Deserialisierung erfolgen

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

4. Verwenden Sie Deep Copy für Serialisierung und Deserialisierung, aber alle Klassen müssen mit [Serialisierbar] markiert sein:

[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. Testen Sie den Effekt nach dem Kopieren

① Drucken Sie vor dem Kopieren die Werte der Werttyp- und Referenztypmitglieder des Originalobjekts aus.
② Drucken Sie für die Originalobjektkopie den Werttyp und die Referenz von aus das kopierte Objekt Der Wert des Typmitglieds
③ Ändern Sie den Wert des Originalobjekts und drucken Sie den Werttyp und das Referenztypmitglied des Originalobjekts erneut
④ Drucken Sie den Wert des kopierten Objektwerttyps und Referenztyps Mitglied wieder

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

Ergebnis:

C#-Beispielanalyse für flache Kopien und tiefe Kopien

Analyse:

Nach tief Beim Kopieren wurden die Referenzelemente der beiden Objekte getrennt. Das Ändern des Werts des Referenztypelements des ursprünglichen Objekts hat keinen Einfluss auf den Wert des Referenztypelements des kopierten Objekts.

Weitere Artikel zur C#-Analyse von Shallow-Copy- und Deep-Copy-Beispielen finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn