欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ASP.NET堆和棧三之引用類型對象拷貝和內(nèi)存分配

 更新時間:2022年08月13日 09:57:18   作者:Darren?Ji  
這篇文章介紹了ASP.NET堆和棧中引用類型對象的拷貝和內(nèi)存分配,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

".NET的堆和棧"系列:

ASP.NET堆和棧一之基本概念和值類型內(nèi)存分配

ASP.NET堆和棧二之值類型和引用類型參數(shù)傳遞和內(nèi)存分配

ASP.NET堆和棧三之引用類型對象拷貝和內(nèi)存分配

ASP.NET堆和棧四之對托管和非托管資源垃圾的回收和內(nèi)存分配

在" ASP.NET堆和棧一之基本概念和值類型內(nèi)存分配"中,了解了"堆"和"棧"的基本概念,以及值類型的內(nèi)存分配。我們知道:當(dāng)執(zhí)行一個方法的時候,值類型實例會在"棧"上分配內(nèi)存,而引用類型實例會在"堆"上分配內(nèi)存,當(dāng)方法執(zhí)行完畢,"棧"上的實例由操作系統(tǒng)自動釋放,"堆"上的實例由.NET Framework的GC進行回收。

在" ASP.NET堆和棧二之值類型和引用類型參數(shù)傳遞和內(nèi)存分配"中,我們了解了值類型參數(shù)和引用類型參數(shù)在傳遞時的內(nèi)存分配情況。

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

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

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

輸出結(jié)果:
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

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

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

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

public class Shoe
{
    public string Color;
}

再次運行,輸出結(jié)果:
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

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

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

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

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

讓引用類Shoe實現(xiàn)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也實現(xiàn)了ICloneable接口;又由于Clone()返回類型是object,所以,在使用Color.Clone()方法之后,需要把object轉(zhuǎn)換成string類型。

現(xiàn)在,在Dude類的CopyDude()方法中,當(dāng)拷貝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());            

}

輸出結(jié)果:   
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  

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

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

當(dāng)然也可以讓同時包含值類型和引用類型成員,同時需要拷貝的類實現(xiàn)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
}

客戶端調(diào)用:

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

輸出結(jié)果:  
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.

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

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

最新評論