C#中object中的MemberwiseClone(浅拷贝)(笔记)

前言:

MemberwiseClone是C#中Object中的成员方法

该方法用于获取对象的浅拷贝对象,可以简单理解为返回一个新的对象


一:在使用MemberwiseClone时,被拷贝的内容可以分为两类

(1):字段为值类型

   若字段为值类型,则会原封不动的拷贝并粘贴过去,且新对象与原对象的值类型互相独立,互不干扰,其中一个修改,另一个置之不理,不做修改!

(2):字段为引用类型  

   若字段为引用类型,那么新对象则是复制老对象中引用类型的引用,而不是被引用的对象,可以简单理解为新老对象是引用同一对象的,一方的引用对象中的内容修改,另一方也会跟着变化,但是并不是两个对象而是二者公用一个对象!

(3)注意:

    对于我个人的理解即使是引用类型的string类型好像是被当成了值类型作为处理,即也是各自管理各自的!

 (若还是不懂可以参考代码和本人自己所绘制的拙劣示意图)


二:代码演示

namespace MemberwiseClone
{
    class MonsterId 
    {
        public int Id;
        public MonsterId(int Id) { this.Id = Id; }
    }
    class Monster 
    {
        public int Hp;
        public string Name;
        public MonsterId monsterId;

        public Monster ShallowCopy() 
        {
            return (Monster)MemberwiseClone();
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("MemberwiseClone浅拷贝");
            Console.WriteLine("----------------------");
            Monster m1 = new()
            {
                Hp = 100,
                Name = "Goblin One",
                monsterId = new MonsterId(1)
            };
            Console.WriteLine("怪物m1创建完毕,信息如下");
            Console.WriteLine("HP={0},Name={1},Id={2}",m1.Hp,m1.Name,m1.monsterId.Id);
            Monster m2 = m1.ShallowCopy();
            Console.WriteLine();
            Console.WriteLine("怪物m2由怪物m1浅拷贝而拷贝完成,信息如下");
            Console.WriteLine("Hp={0},Name={1},Id={2}",m2.Hp,m2.Name,m2.monsterId.Id);
            Console.WriteLine("-------------------------------------------------------------------");

            //对值类型进行修改(string)
            m1.Hp = 200;
            m1.Name = "Goblin Two";
            m2.Hp = 300;
            m2.Name = "Goblin Three";
            Console.WriteLine("HP={0},Name={1},Id={2}", m1.Hp, m1.Name, m1.monsterId.Id);
            Console.WriteLine("Hp={0},Name={1},Id={2}", m2.Hp, m2.Name, m2.monsterId.Id);
            Console.WriteLine("-------------------------------------------------------------------");
            //对引用类型进行修改
            m1.monsterId.Id = 123;
            Console.WriteLine("HP={0},Name={1},Id={2}", m1.Hp, m1.Name, m1.monsterId.Id);
            Console.WriteLine("Hp={0},Name={1},Id={2}", m2.Hp, m2.Name, m2.monsterId.Id);
            Console.WriteLine("-------------------------------------------------------------------");
            m2.monsterId.Id = 123123;
            Console.WriteLine("HP={0},Name={1},Id={2}", m1.Hp, m1.Name, m1.monsterId.Id);
            Console.WriteLine("Hp={0},Name={1},Id={2}", m2.Hp, m2.Name, m2.monsterId.Id);

            //总结:
            //可以看到在修改值类型时m1,m2各自管理各自的值类型(包括string)成员
            //但是在修改其中一方的引用类型成员时,另一方也会同步,这是因为二者的引用一致,二者指向同一地址
        }
    }
}

运行结果如下:

三:总结

   (1):正如上述所示,这就是在利用浅拷贝时值类型和引用类型的区别!

   (2):另外对于浅拷贝而言,我们还可以封装新的Clone方法利用MemberwiseClone()中的处理,再加上一些特殊逻辑处理完善克隆复制的操作!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值