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

首頁 > 學院 > 開發設計 > 正文

.NET的堆和棧03,引用類型對象拷貝以及內存分配

2019-11-14 16:34:23
字體:
來源:轉載
供稿:網友

在" .NET的堆和棧01,基本概念、值類型內存分配"中,了解了"堆"和"棧"的基本概念,以及值類型的內存分配。我們知道:當執行一個方法的時候,值類型實例會在"棧"上分配內存,而引用類型實例會在"堆"上分配內存,當方法執行完畢,"棧"上的實例由操作系統自動釋放,"堆"上的實例由.NET Framework的GC進行回收。


在" .NET的堆和棧02,值類型和引用類型參數傳遞以及內存分配"中,我們了解了值類型參數和引用類型參數在傳遞時的內存分配情況。


而本篇的重點要放在:引用類型對象拷貝以及內存分配。

 

主要包括:
■  引用類型對象拷貝 成員都是值類型
■  引用類型對象拷貝 包含引用類型成員

 

  引用類型對象拷貝 成員都是值類型

public struct Shoe{               public string Color;           }            public class Dude           {                public string Name;                public Shoe RightShoe;                public Shoe LeftShoe;                 public Dude CopyDude()                {                     Dude newPerson = new Dude();                     newPerson.Name = Name;                     newPerson.LeftShoe = LeftShoe;                     newPerson.RightShoe = RightShoe;                      return newPerson;                }                 public override string ToString()                {                     return (Name + " : Dude!, I have a " + RightShoe.Color  +                         " shoe on my right foot, and a " +                          LeftShoe.Color + " on my left foot.");                }            }           public static void Main()           {                  Dude Bill = new Dude();                  Bill.Name = "Bill";                  Bill.LeftShoe = new Shoe();                  Bill.RightShoe = new Shoe();                  Bill.LeftShoe.Color = Bill.RightShoe.Color = "Blue";                   Dude Ted =  Bill.CopyDude();                  Ted.Name = "Ted";                  Ted.LeftShoe.Color = Ted.RightShoe.Color = "Red";                   Console.WriteLine(Bill.ToString());                  Console.WriteLine(Ted.ToString());                       }

 

輸出結果:
Bill : Dude!, I have a Red shoe on my right foot, and a Red on my left foot
Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot

 

以上,當引用類型的屬性、成員都是值類型的時候,拷貝是完全拷貝。

16

 

  引用類型對象拷貝 包含引用類型成員

把Shoe由struct值類型改成引用類型class。

public class Shoe{               public string Color;           }

 

再次運行,輸出結果:
Bill : Dude!, I have a Red shoe on my right foot, and a Red on my left foot
Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot

 

當Dude類包含引用類型屬性Shoe的時候,在托管堆上的情況是這樣的:
17  

 

拷貝后,2個Dude的Shoe類型的屬性指向了同一個托管堆內的Shoe實例,改變Shoe的值會同時影響到2個Dude。


很顯然,這不是我們期望的完全拷貝,如何做到完全拷貝呢?
--實現ICloneable接口       

 

ICloneable接口的Clone()方法,允許我們在拷貝的時候,進行一些自定義設置。

 

讓引用類Shoe實現ICloneable接口。

public class Shoe : ICloneable             {                  public string Color;                   public object Clone()                  {                      Shoe newShoe = new Shoe();                      newShoe.Color = Color.Clone() as string;                      return newShoe;                  }             }


以上,Shoe的string類型屬性Color之所以可以使用Color.Clone()方法,是因為string也實現了ICloneable接口;又由于Clone()返回類型是object,所以,在使用Color.Clone()方法之后,需要把object轉換成string類型。


現在,在Dude類的CopyDude()方法中,當拷貝Shoe類型屬性的時候,就可以使用Shoe獨有的拷貝方法Clone()。

public Dude CopyDude()                {                    Dude newPerson = new Dude();                     newPerson.Name = Name;                     newPerson.LeftShoe = LeftShoe.Clone() as Shoe;                     newPerson.RightShoe = RightShoe.Clone() as Shoe;                      return newPerson;                }

 

客戶端程序。

public static void Main()           {                  Dude Bill = new Dude();                  Bill.Name = "Bill";                  Bill.LeftShoe = new Shoe();                  Bill.RightShoe = new Shoe();                  Bill.LeftShoe.Color = Bill.RightShoe.Color = "Blue";                   Dude Ted =  Bill.CopyDude();                  Ted.Name = "Ted";                  Ted.LeftShoe.Color = Ted.RightShoe.Color = "Red";                   Console.WriteLine(Bill.ToString());                  Console.WriteLine(Ted.ToString());                        }

 

輸出結果:  
Bill : Dude!, I have a Blue shoe on my right foot, and a Blue on my left foot
Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot  

 

這正是我們期望的完全拷貝!

 

完全拷貝,托管堆上的情況是這樣的:
18

 

當然也可以讓同時包含值類型和引用類型成員,同時需要拷貝的類實現ICloneable接口。

public class Dude: ICloneable           {                public string Name;                public Shoe RightShoe;                public Shoe LeftShoe;                 public override string ToString()                {                     return (Name + " : Dude!, I have a " + RightShoe.Color  +                         " shoe on my right foot, and a " +                          LeftShoe.Color + " on my left foot.");                    }                  #region ICloneable Members                   public object Clone()                  {                       Dude newPerson = new Dude();                       newPerson.Name = Name.Clone() as string;                       newPerson.LeftShoe = LeftShoe.Clone() as Shoe;                       newPerson.RightShoe = RightShoe.Clone() as Shoe;                        return newPerson;                  }                   #endregion             }

 

客戶端調用。

public static void Main()           {               Class1 pgm = new Class1();                   Dude Bill = new Dude();                  Bill.Name = "Bill";                  Bill.LeftShoe = new Shoe();                  Bill.RightShoe = new Shoe();                  Bill.LeftShoe.Color = Bill.RightShoe.Color = "Blue";                   Dude Ted =  Bill.Clone() as Dude;                  Ted.Name = "Ted";                  Ted.LeftShoe.Color = Ted.RightShoe.Color = "Red";                   Console.WriteLine(Bill.ToString());                  Console.WriteLine(Ted.ToString());                        }

 

輸出結果: 
Bill : Dude!, I have a Blue shoe on my right foot, and a Blue on my left foot.
Ted : Dude!, I have a Red shoe on my right foot, and a Red on my left foot.

 

也是我們期望的完全拷貝!

 

參考資料:
C# Heap(ing) Vs Stack(ing) in .NET: Part III

 

".NET的堆和棧"系列包括:

.NET的堆和棧01,基本概念、值類型內存分配

.NET的堆和棧02,值類型和引用類型參數傳遞以及內存分配

.NET的堆和棧03,引用類型對象拷貝以及內存分配

.NET的堆和棧04,對托管和非托管資源的垃圾回收以及內存分配


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高安市| 天水市| 林西县| 淳化县| 永安市| 麦盖提县| 思南县| 乡宁县| 广南县| 桓仁| 老河口市| 孝感市| 祁东县| 余干县| 北川| 五指山市| 潍坊市| 遵义县| 介休市| 株洲市| 永德县| 清新县| 房山区| 萝北县| 横峰县| 来安县| 获嘉县| 邹平县| 广东省| 云霄县| 太湖县| 乐亭县| 贡嘎县| 黔西县| 利辛县| 南澳县| 林州市| 平湖市| 宝应县| 凤阳县| 中超|