国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#淺拷貝和深拷貝實例解析

2020-01-24 02:32:13
字體:
來源:轉載
供稿:網友

在有些時候,我們需要從數據庫讀取數據填充對象或從硬盤讀取文件填充對象,但是這樣做相對耗時。這時候我們就想到了對象的拷貝。本文即以實例形式解析了C#淺拷貝和深拷貝的用法。具體如下:

一、淺拷貝

1.什么是"淺拷貝":

當針對一個對象前拷貝的時候,對于對象的值類型成員,會復制其本身,對于對象的引用類型成員,僅僅復制對象引用,這個引用指向托管堆上的對象實例。

2.有一個對象,包含引用類型的類成員和值類型的struct成員

Cinema包含引用類型成員Room和值類型成員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.測試拷貝后的效果

①打印出原先對象拷貝前值類型和引用類型成員的值
②對原先對象拷貝,打印出復制對象值類型和引用類型成員的值
③改變原先對象的值,再次打印原先對象的值類型和引用類型成員的值
④再次打印復制對象值類型和引用類型成員的值

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

運行結果如下:

分析:

淺拷貝關鍵點是對引用類型拷貝的是對象引用,這個引用指向托管堆上的對象實例。改變原對應引用類型的值,會影響到復制對象。

二、深拷貝

1.什么是"深拷貝"

對引用成員指向的對象也進行復制,在托管堆上賦值原先對象實例所包含的數據,再在托管堆上創建新的對象實例。

2.通過對每個對象成員進行復制進行深拷貝

    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.也可以通過序列化和反序列化進行深拷貝

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

4.采用序列化和反序列化深拷貝,但必須把所有的類打上[Serializable],測試代碼如下:

  [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.測試拷貝后的效果

①打印出原先對象拷貝前值類型和引用類型成員的值
②對原先對象拷貝,打印出復制對象值類型和引用類型成員的值
③改變原先對象的值,再次打印原先對象的值類型和引用類型成員的值
④再次打印復制對象值類型和引用類型成員的值

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

結果:

 

分析:

深拷貝后,兩個對象的引用成員已經分離,改變原先對象引用類型成員的值并不會對復制對象的引用類型成員值造成影響。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 岳普湖县| 福建省| 四子王旗| 安溪县| 杭州市| 台湾省| 定西市| 手游| 新龙县| 桃园市| 济宁市| 太和县| 依兰县| 台前县| 无棣县| 岱山县| 永定县| 土默特右旗| 定安县| 神池县| 修水县| 尉犁县| 廉江市| 伊吾县| 新邵县| 密云县| 沛县| 东方市| 清镇市| 灵川县| 汝南县| 荣成市| 内黄县| 庐江县| 乌苏市| 随州市| 屏东市| 咸丰县| 丰都县| 仁布县| 赞皇县|