前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# MemberwiseClone 实现深浅复制

C# MemberwiseClone 实现深浅复制

作者头像
科控物联
发布2023-09-01 08:09:07
5120
发布2023-09-01 08:09:07
举报
文章被收录于专栏:科控自动化

浅复制:在C#中调用 MemberwiseClone() 方法即为浅复制。如果字段是值类型的,则对字段执行逐位复制,如果字段是引用类型的,则复制对象的引用,而不复制对象,因此:原始对象和其副本引用同一个对象!

深复制:如果字段是值类型的,则对字段执行逐位复制,如果字段是引用类型的,则把引用类型的对象指向一个全新的对象!

研究下官方的例子,都加上了注释。

代码语言:javascript
复制
using System;

public class IdInfo
{
    public int IdNumber; // 身份证号码

    public IdInfo(int IdNumber)
    {
        this.IdNumber = IdNumber;
    }
}

public class Person
{
    public int Age; // 年龄
    public string Name; // 姓名
    public IdInfo IdInfo; // 身份信息

    public Person ShallowCopy()
    {
       return (Person) this.MemberwiseClone(); // 浅复制,只复制对象的字段值,而不复制引用类型的实例
    }

    public Person DeepCopy()
    {
       Person other = (Person) this.MemberwiseClone(); // 浅复制,复制对象的字段值
       other.IdInfo = new IdInfo(IdInfo.IdNumber); // 创建新的IdInfo对象,并复制原始对象的IdNumber值
       other.Name = String.Copy(Name); // 复制原始对象的Name值
       return other; // 返回深复制的Person对象
    }
}

public class Example
{
    public static void Main()
    {
        // 创建Person实例并为其字段赋值
        Person p1 = new Person();
        p1.Age = 42;
        p1.Name = "Sam";
        p1.IdInfo = new IdInfo(6565);

        // 执行p1的浅复制并赋值给p2
        Person p2 = p1.ShallowCopy();

        // 显示p1和p2的值
        Console.WriteLine("Original values of p1 and p2:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);

        // 修改p1的属性值并显示p1和p2的值
        p1.Age = 32;
        p1.Name = "Frank";
        p1.IdInfo.IdNumber = 7878;
        Console.WriteLine("\nValues of p1 and p2 after changes to p1:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);

        // 执行p1的深复制并赋值给p3
        Person p3 = p1.DeepCopy();
        // 修改p1类的成员为新值以展示深复制
        p1.Name = "George";
        p1.Age = 39;
        p1.IdInfo.IdNumber = 8641;
        Console.WriteLine("\nValues of p1 and p3 after changes to p1:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p3 instance values:");
        DisplayValues(p3);
    }

    public static void DisplayValues(Person p)
    {
        Console.WriteLine("      Name: {0:s}, Age: {1:d}", p.Name, p.Age);
        Console.WriteLine("      Value: {0:d}", p.IdInfo.IdNumber);
    }
}

执行过程就是,先创建p1实例,再执行p1浅复制并赋值给p2,再修改p1的值。结果如下:

无论是浅复制还是深复制,副本中的值类型都是全新的!

浅复制中原始对象和副本的引用类型指向同一内存地址,所以,修改了P1的IdInfo会同时影响P2的IdInfo。

再执行p1浅复制并赋值给p3,再修改p1的值。结果如下:

深复制中原始对象和副本的引用类型指向各自的地址,两者完全是两个不同的对象!

因此:修改P1不会影响P3.

深浅复制主要用于当创建一个对象需要消耗过多资源时,可以采取复制的方法提升效率!

大话设计模式的原话是这样滴:当你New一个对象时,每New一次,都需要执行一个构造函数,如果构造函数的执行时间很长,那么多次New对象时会大大拉低程序执行效率,因此:一般在初始化信息不发生变化的前提下,克隆是最好的办法,这既隐藏了对象的创建细节,又大大提升了性能!

网关运行历史监控

最近开发网关的时候经常用到,就记录一下。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 科控物联 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档