佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 淺談.net平臺下深拷貝和淺拷貝

淺談.net平臺下深拷貝和淺拷貝

熱門標(biāo)簽:電商新玩法 國美全國運(yùn)營中心 百度AI接口 客戶服務(wù) 人工智能 電銷業(yè)務(wù) 網(wǎng)站排名優(yōu)化 科大訊飛語音識別系統(tǒng)

基本概念:

淺拷貝:指對象的字段被拷貝,而字段引用的對象不會(huì)被拷貝,拷貝對象和原對象僅僅是引用名稱有所不同,但是它們共用一份實(shí)體。對任何一個(gè)對象的改變,都會(huì)影響到另外一個(gè)對象。大部分的引用類型,實(shí)現(xiàn)的都是淺拷貝,引用類型對象之間的賦值,就是復(fù)制一個(gè)對象引用地址的副本,而指向的對象實(shí)例仍然是同一個(gè)。

深拷貝:指對象的子段被拷貝,同時(shí)字段引用的對象也進(jìn)行了拷貝。深拷貝創(chuàng)建的是整個(gè)源對象的結(jié)構(gòu),拷貝對象和原對象相互獨(dú)立,不共享任何實(shí)例數(shù)據(jù),修改一個(gè)對象不會(huì)影響到另一個(gè)對象。值類型之間的賦值操作,執(zhí)行的就是深拷貝。

基本概念之參考代碼:

復(fù)制代碼 代碼如下:

class Program
    {
        static void Main(string[] args)
        {
            Student s1 = new Student("li", 23);

            //淺拷貝
            Student s2 = s1;
            s2.Age = 27;
            s1.ShowInfo();//li's age is 27

            //深拷貝
            int i = 12;
            int j = i;
            j = 22;
            Console.WriteLine(i);//12

            Console.Read();
        }
    }

    class Student
    {
        public string Name;
        public int Age;

        public Student(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public void ShowInfo()
        {
            Console.WriteLine("{0}'s age is {1}", Name, Age);
        }
    }


分析:

在上例中,實(shí)例s2對s1進(jìn)行了淺拷貝,對s2中的Age字段進(jìn)行更改,繼而影響實(shí)例s1中的Age字段。

深拷貝中,僅僅是值類型間簡單的賦值,對“j”做出的更改不會(huì)更改“i”的值。

深淺拷貝的實(shí)現(xiàn):

復(fù)制代碼 代碼如下:

public object Clone()
{
return this.MemberwiseClone();
}

MemberwiseClone:創(chuàng)建一個(gè)淺表副本。過程是創(chuàng)建一個(gè)新對象,然后將當(dāng)前對象的非靜態(tài)字段復(fù)制到該新對象。如果字段是值類型,則對該字段執(zhí)行逐位復(fù)制,如果字段是引用類型,則復(fù)制引用但不復(fù)制引用對象。

參考代碼:

復(fù)制代碼 代碼如下:

class Program
    {
        static void Main(string[] args)
        {
            ClassA ca = new ClassA();
            ca.value = 88;
            ClassA ca2 = new ClassA();
            ca2 = (ClassA)ca.Clone();
            ca2.value = 99;
            Console.WriteLine(ca.value + "-----" + ca2.value);//88---99

            ClassB cb = new ClassB();
            cb.Member.value = 13;

            ClassB cb2 = (ClassB)cb.Clone();
            cb2.Member.value = 7;
            Console.WriteLine(cb.Member.value.ToString() + "------" + cb2.Member.value.ToString());//淺拷貝:7---7      深拷貝:13----7          

            Console.Read();
        }
    }

    public class ClassA : ICloneable
    {
        public int value = 0;

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }

    public class ClassB : ICloneable
    {
        public ClassA Member = new ClassA();

        public object Clone()
        {
            //淺拷貝
            return this.MemberwiseClone();

            //深拷貝
            ClassB obj = new ClassB();
            obj.Member = (ClassA)Member.Clone();
            return obj;
        }
    }

分析:

上例中,ca2復(fù)制ca對象,實(shí)現(xiàn)了深度拷貝。結(jié)果如同代碼中顯示:ca2中值類型字段的改變并不影響ca中的字段。

在類ClassB中,引用類型成員Member,如果用ClassA中的clone方法實(shí)現(xiàn)則僅僅實(shí)現(xiàn)的是淺拷貝,在上述參考代碼中能夠看出:對cb2的member的改變影響著cb。但是當(dāng)使用參考代碼中的深度拷貝后,對cb2的member的改變則不會(huì)影響著cb。

在網(wǎng)上找到一個(gè)綜合的例子,有對比的來進(jìn)行解釋深淺拷貝:

實(shí)例1:

復(fù)制代碼 代碼如下:

public class Sex:ICloneable
    {
        private string _PSex;
        public string PSex
        {
            set{ _PSex = value;}
            get { return _PSex; }
        }

        //public object Clone()
        //{
        //    return this.MemberwiseClone();
        //}
    }

    public class Person : ICloneable
    {

        private Sex sex = new Sex();
        public int aa = 3;

        public string pSex
        {
            set { sex.PSex = value; }
            get { return sex.PSex; }
        }
        private string _PName;
        public string PName
        {
            set { this._PName = value; }
            get { return this._PName; }
        }

        public void ShowPersonInfo()
        {
            Console.WriteLine("-------------------------");
            Console.WriteLine("Name:{0} Sex:{1}", _PName, this.pSex);
            Console.WriteLine("-------------------------");
            Console.WriteLine(this.aa);
        }
        //淺拷貝
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        //深拷貝
        public object DeepClone()
        {
            Person newP = new Person();
            newP.PName = this._PName;
            newP.pSex = this.pSex;
            return newP;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("原對象:");
            Person p = new Person();
            p.PName = "Lee";
            p.pSex = "男";

            p.ShowPersonInfo();//原對象:lee 男 3

            //淺拷貝       
            Person copy = (Person)p.Clone();
            //深拷貝
            Person dcopy = (Person)p.DeepClone();

            Console.WriteLine("修改后的原對象:");
            p.PName = "Zhao";
            p.pSex = "女";
            p.aa = 1;
            p.ShowPersonInfo();//zhao 女 1

            Console.WriteLine("修改后的淺拷貝對象:");
            copy.ShowPersonInfo();//lee 女 3

            Console.WriteLine("修改后的深拷貝對象:");
            dcopy.ShowPersonInfo();//lee 男 3

            Console.WriteLine("直接拷貝對象:");
            Person PP = p;
            PP.ShowPersonInfo();//zhao 女 1

            Console.ReadLine();
        }
    }

分析:

首先需指出,上例中在類Sex中,加入Clone方法和不加對實(shí)例中運(yùn)算結(jié)果沒有影響。

類Person中,引用類型但卻是string類型的PName字段,引用類型pSex字段,值類型aa。

初始值:lee 男 3  (先進(jìn)行深淺拷貝)

修改值:zhao 女 1

淺拷貝值:lee 女 3

深拷貝值:lee 男 3

直接拷貝值:趙 女 1

結(jié)果:上述可以說是對深淺拷貝中經(jīng)常遇到的幾種類型做出總結(jié)和對比,相信在一番體悟后可以學(xué)到一些知識。

實(shí)例2:

復(fù)制代碼 代碼如下:

class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 2, 3, 4, 5 };
            int[] numbersCopy = new int[5];
            numbers.CopyTo(numbersCopy, 0);
            numbersCopy[2] = 0;

            int[] numbers1 = { 2, 3, 4, 5 };
            int[] numbersClone1 = (int[])numbers1.Clone();
            numbersClone1[2] = 0;

            Console.Write(numbers[2] + "---" + numbersCopy[2]);//4---0
            Console.Write(numbers1[2] + "---" + numbersClone1[2]);//4--0


            //數(shù)組的復(fù)制也就是引用傳遞,指向的是同一個(gè)地址
            int[] numbers2 = { 2, 3, 4, 5 };
            int[] numbers2Copy = numbers2;
            numbers2Copy[2] = 0;

            Console.Write(numbers2[2]);//0
            Console.Write(numbers2Copy[2]);//0

            Console.Read();
        }
    }


暫不做分析,認(rèn)真領(lǐng)悟。

標(biāo)簽:拉薩 廈門 攀枝花 南平 咸寧 棗莊 益陽 POS機(jī)

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺談.net平臺下深拷貝和淺拷貝》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    新津县| 绥江县| 封开县| 克山县| 聂拉木县| 武山县| 东海县| 长兴县| 临泉县| 睢宁县| 交城县| 蓝山县| 鄢陵县| 张掖市| 福清市| 阳山县| 友谊县| 博罗县| 高州市| 武强县| 金华市| 宣武区| 双流县| 鹤山市| 宁陵县| 晋宁县| 闻喜县| 南木林县| 高密市| 张家港市| 塔河县| 崇义县| 孝义市| 汝阳县| 南汇区| 贡嘎县| 连江县| 嘉峪关市| 禹城市| 西乡县| 资源县|