• (C#基础)深浅拷贝理解


    一方面感觉实在无趣,不知道做什么了,纯粹来个打字练习,于是有了这个。

    二方面深感自己C#基础之薄弱,于是对着园友的文章一边看,一边练习,因为很多次看了,没有多久就忘了,还有练习过程中会出现一些问题,这些问题往往是自己最容易忽视的,还有可以举一反三,引申一些其他知识点,于是有了这个。

    浅拷贝代码

     public class Room
        {
           public int _maxSeat;
           public string _address;
           public Room(int maxSeat,string address)
           {
               this._maxSeat = maxSeat;
               this._address = address;
           }
        }
       public struct Film
       {
           public string _name;
           public int _bigmax;
           public Film(string name,int bigmax)
           {
               this._name = name;
               this._bigmax = bigmax;
           }
       }
    
       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();// 对引用类型实施浅复制
           }
           
       }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace dazilianxi
    {
        class Program
        {
            static void Main(string[] args)
            {
                Room room1 = new Room(60,"广州");
                Film film1 = new Film("家园防线",100);
                Cinema cinema1 = new Cinema(room1, film1);
                Cinema cinema2=(Cinema) cinema1.Clone();
                Console.WriteLine("拷贝之前,结构成员的字段值为{0},地址{2},引用类型成员值是{1},最大值{3}",cinema1._film._name,cinema1._room._maxSeat,cinema1._film._bigmax,cinema1._room._address);
    
                Console.WriteLine("拷贝之后,结构成员的字段值是{0},地址{2},引用类型成员值是{1},最大值{3}", cinema2._film._name, cinema2._room._maxSeat, cinema2._film._bigmax, cinema2._room._address);
               //修改拷贝之前引用类型的字段
                cinema1._film._name = "极品飞车";
                cinema1._film._bigmax = 250;
                cinema1._room._address = "香港";
                cinema1._room._maxSeat = 80;
    
                Console.WriteLine("拷贝之前,结构成员的字段值为{0},地址{2},引用类型成员值是{1},最大值{3}", cinema1._film._name, cinema1._room._maxSeat, cinema1._film._bigmax, cinema1._room._address);
    
                Console.WriteLine("拷贝之后,结构成员的字段值是{0},地址{2},引用类型成员值是{1},最大值{3}", cinema2._film._name, cinema2._room._maxSeat, cinema2._film._bigmax, cinema2._room._address);
               
                //说明浅度复制,结构类型值没有改变,引用类型值发生改变
                Console.ReadKey();
            }
        }
    }

    运行结果:

     浅拷贝关键点是对引用类型拷贝的是对象引用,这个引用指向托管堆上的对象实例。改变原对应引用类型的值,会影响到复制对象。

    深拷贝代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace dazilianxi
    {
       public class Room
        {
           public int _maxSeat;
           public string _address;
           public Room()
           {
           }
           public Room(int maxSeat,string address)
           {
               this._maxSeat = maxSeat;
               this._address = address;
           }
        }
       public struct Film
       {
           public string _name;
           public int _bigmax;
           public Film(string name,int bigmax)
           {
               this._name = name;
               this._bigmax = bigmax;
           }
       }
    
       public class Cinema
       {
           public Room _room;
           public Film _film;
    
           public Cinema(Room room,Film film)
           {
               this._room = room;
               this._film = film;
           }
           public object Clone2()
           {
               Room room = new Room();
    room._address = this._room._address; room._maxSeat
    = this._room._maxSeat;//复制当前引用类型成员的值到新对象 Film film = this._film; //值类型直接赋值 Cinema cinema = new Cinema(room, film); return cinema; } } }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace dazilianxi
    {
        class Program
        {
            static void Main(string[] args)
            {
                Room room1 = new Room(60,"广州");
                Film film1 = new Film("家园防线",100);
                Cinema cinema1 = new Cinema(room1, film1);
                Cinema cinema2=(Cinema) cinema1.Clone2();//深拷贝
                Console.WriteLine("拷贝之前,结构成员的字段值为{0},地址{2},引用类型成员值是{1},最大值{3}",cinema1._film._name,cinema1._room._maxSeat,cinema1._film._bigmax,cinema1._room._address);
    
                Console.WriteLine("拷贝之后,结构成员的字段值是{0},地址{2},引用类型成员值是{1},最大值{3}", cinema2._film._name, cinema2._room._maxSeat, cinema2._film._bigmax, cinema2._room._address);
               //修改拷贝之前引用类型的字段
                cinema1._film._name = "极品飞车";
                cinema1._film._bigmax = 250;
                cinema1._room._address = "香港";
                cinema1._room._maxSeat = 80;
    
                Console.WriteLine("拷贝之前,结构成员的字段值为{0},地址{2},引用类型成员值是{1},最大值{3}", cinema1._film._name, cinema1._room._maxSeat, cinema1._film._bigmax, cinema1._room._address);
    
                Console.WriteLine("拷贝之后,结构成员的字段值是{0},地址{2},引用类型成员值是{1},最大值{3}", cinema2._film._name, cinema2._room._maxSeat, cinema2._film._bigmax, cinema2._room._address);
               
                //说明浅度复制,结构类型值没有改变,引用类型值发生改变
                Console.ReadKey();
            }
        }
    }

    运行结果:

    深拷贝后,两个对象的引用成员已经分离,改变原先对象引用类型成员的值并不会对复制对象的引用类型成员值造成影响。

    深度拷贝序列化

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    
    namespace dazilianxi
    {
        [Serializable]
       public class Room
        {
           public int _maxSeat;
           public string _address;
           public Room()
           {
           }
           public Room(int maxSeat,string address)
           {
               this._maxSeat = maxSeat;
               this._address = address;
           }
        }
        [Serializable]
       public struct Film
       {
           public string _name;
           public int _bigmax;
           public Film(string name,int bigmax)
           {
               this._name = name;
               this._bigmax = bigmax;
           }
       }
    
        [Serializable]
       public class Cinema
       {
           public Room _room;
           public Film _film;
    
           public Cinema(Room room,Film film)
           {
               this._room = room;
               this._film = film;
           }
           public object Clone3()
           {
               BinaryFormatter bf = new BinaryFormatter();
               MemoryStream ms = new MemoryStream();
               bf.Serialize(ms, this); //复制到流中
               ms.Position = 0;
               return (bf.Deserialize(ms));
           }
       }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace dazilianxi
    {
        class Program
        {
            static void Main(string[] args)
            {
                Room room1 = new Room(60,"广州");
                Film film1 = new Film("家园防线",100);
                Cinema cinema1 = new Cinema(room1, film1);
                Cinema cinema2 = (Cinema)cinema1.Clone3();//深拷贝
                Console.WriteLine("拷贝之前,结构成员的字段值为{0},地址{2},引用类型成员值是{1},最大值{3}",cinema1._film._name,cinema1._room._maxSeat,cinema1._film._bigmax,cinema1._room._address);
    
                Console.WriteLine("拷贝之后,结构成员的字段值是{0},地址{2},引用类型成员值是{1},最大值{3}", cinema2._film._name, cinema2._room._maxSeat, cinema2._film._bigmax, cinema2._room._address);
               //修改拷贝之前引用类型的字段
                cinema1._film._name = "极品飞车";
                cinema1._film._bigmax = 250;
                cinema1._room._address = "香港";
                cinema1._room._maxSeat = 80;
    
                Console.WriteLine("拷贝之前,结构成员的字段值为{0},地址{2},引用类型成员值是{1},最大值{3}", cinema1._film._name, cinema1._room._maxSeat, cinema1._film._bigmax, cinema1._room._address);
    
                Console.WriteLine("拷贝之后,结构成员的字段值是{0},地址{2},引用类型成员值是{1},最大值{3}", cinema2._film._name, cinema2._room._maxSeat, cinema2._film._bigmax, cinema2._room._address);
               
                //说明浅度复制,结构类型值没有改变,引用类型值发生改变
                Console.ReadKey();
            }
        }
    }

    运行结果:

    参考:http://www.cnblogs.com/darrenji/p/3601523.html

  • 相关阅读:
    [LeetCode每日1题][简单] 169. 多数元素
    [LeetCode每日1题][简单] 1013. 将数组分成和相等的三个部分
    [LeetCode每日1题][中等] 322. 零钱兑换
    [LeetCode每日1题][中等] 面试题59
    软工实践个人总结
    2019 SDN大作业
    2019 SDN上机第7次作业
    第01组 Beta版本演示
    如果有一天我变得很有钱组——alpha冲刺day7
    如果有一天我变得很有钱组——alpha冲刺day6
  • 原文地址:https://www.cnblogs.com/annabook/p/4945093.html
Copyright © 2020-2023  润新知