C# 对象拷贝

C# 实现对象的深拷贝 C# 实现对象的深拷贝在 C# 编程中,对象的拷贝是一个常见的操作。有时候我们需要对对象进行深拷贝,即创建一个与原始对象完全相等但独立于原始对象的新对象。本文将介绍如何使用 C# 实现对象的深拷贝,并提供相应的源代码和描述。在 C# 中,对象的浅拷贝可以通过 方法实现。然而,该方法只会复制对象的字段,并不复制引用类型的成员。因此,为了实现对象的深拷贝,我们需要采用其他方法。接下来,我们将介绍两种常用的方式来实现对象的深拷贝:序列化和反射。方法一:使用序列化实现深拷贝首先,我们需要确保对象的类和成员都是可序 阅读详情

深拷贝

  1. 利用 Newtonsoft.Json 序列化
/*
利用 json 进行深拷贝
*/
using System;
using Newtonsoft.Json;

namespace Copy
{
    class Program
    {
        static void Main(string[] args)
        {
            
            var obj = new Model();
            obj.a = "1";
            obj.b = "2";
            var strObj  = JsonConvert.SerializeObject(obj);
            var newObj = JsonConvert.DeserializeObject<Model>(strObj);
            newObj.a = "3";
            newObj.b = "4";
            Console.ReadKey();
        }
    }
}

  1. XML 序列化
		/// <summary>
        /// xml序列化的方式实现深拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T XmlDeepCopy<T>(T t)
        {
            //创建Xml序列化对象
            XmlSerializer xml = new XmlSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream())//创建内存流
            {
                //将对象序列化到内存中
                xml.Serialize(ms, t);
                ms.Position = default;//将内存流的位置设为0
                return (T)xml.Deserialize(ms);//继续反序列化
            }
        }
  1. 内存序列化
        /// <summary>
        /// 二进制序列化的方式进行深拷贝
        /// 确保需要拷贝的类里的所有成员已经标记为 [Serializable] 如果没有加该特性特报错
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T BinaryDeepCopy<T>(T t)
        {
            //创建二进制序列化对象
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())//创建内存流
            {
                //将对象序列化到内存中
                bf.Serialize(ms, t);
                ms.Position = default;//将内存流的位置设为0
                return (T)bf.Deserialize(ms);//继续反序列化
            }
        }
        // 同上方法
		public static T DeepCopy<T>(T obj)
		{
		  object retval;
		  using (MemoryStream ms = new MemoryStream())
		  {
		    BinaryFormatter bf = new BinaryFormatter();
		    //序列化成流
		    bf.Serialize(ms, obj);
		    ms.Seek(0, SeekOrigin.Begin);
		    //反序列化成对象
		    retval = bf.Deserialize(ms);
		    ms.Close();
		  }
		  return (T)retval;
		}
  1. Reflection
public static void CopyValue(object origin,object target)
  {
   System.Reflection.PropertyInfo[] properties = (target.GetType()).GetProperties();
   System.Reflection.FieldInfo[] fields = (origin.GetType()).GetFields();
   for ( int i=0; i< fields.Length; i++)
   {
    for ( int j=0; j< properties.Length; j++)
    {
     if (fields[i].Name == properties[j].Name && properties[j].CanWrite)
     {
      properties[j].SetValue(target,fields[i].GetValue(origin),null);
     }
    }
   }
  }

浅拷贝

  1. MemberwiseClone
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);
       other.Name = String.Copy(Name);
       return other;
    }
}

public class Example
{
    public static void Main()
    {
        // Create an instance of Person and assign values to its fields.
        Person p1 = new Person();
        p1.Age = 42;
        p1.Name = "Sam";
        p1.IdInfo = new IdInfo(6565);

        // Perform a shallow copy of p1 and assign it to p2.
        Person p2 = p1.ShallowCopy();

        // Display values of p1, p2
        Console.WriteLine("Original values of p1 and p2:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);
        
        // Change the value of p1 properties and display the values of p1 and 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);

        // Make a deep copy of p1 and assign it to p3.
        Person p3 = p1.DeepCopy();
        // Change the members of the p1 class to new values to show the deep copy.
        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);
    }
}
// The example displays the following output:
//       Original values of p1 and p2:
//          p1 instance values:
//             Name: Sam, Age: 42
//             Value: 6565
//          p2 instance values:
//             Name: Sam, Age: 42
//             Value: 6565
//       
//       Values of p1 and p2 after changes to p1:
//          p1 instance values:
//             Name: Frank, Age: 32
//             Value: 7878
//          p2 instance values:
//             Name: Sam, Age: 42
//             Value: 7878
//       
//       Values of p1 and p3 after changes to p1:
//          p1 instance values:
//             Name: George, Age: 39
//             Value: 8641
//          p3 instance values:
//             Name: Frank, Age: 32
//             Value: 7878

参考
https://www.cnblogs.com/heheblog/archive/2018/07/16/net_study_20180716.html
https://www.cnblogs.com/lijIT/p/4572059.html
https://docs.microsoft.com/zh-cn/dotnet/api/system.object.memberwiseclone?view=netframework-4.8#System_Object_MemberwiseClone

深入解析 C# 中的 Clone 方法 —— 实现对象的深拷贝与浅拷贝 Clone方法是ICloneable接口中定义的一个方法,用于创建当前对象的副本。通过实现ICloneable接口并重写Clone方法,您可以控制对象是如何被复制的。以下是ICloneableClone方法返回一个新对象,该对象是原始对象的副本。根据实现的不同,这个副本可以是浅拷贝(shallow copy)或深拷贝(deep copy)。在进行Clone方法开发的过程中,我们积累了宝贵的经验和教训。 阅读详情

相关推荐

Lumerical官方案例、FDTD时域有限差分法仿真学习(十三)——多模干涉耦合器(MMI)

计算通过 1×2 端口多模干涉 (MMI) 耦合器的宽带传输和光损耗。 使用设备 S 参数在 INTERCONNECT 中创建 MMI 的紧凑模型。 它还展示了如何使用 CML 编译器提取这些参数以生成紧凑模型。 一、概述 了解模拟工作流程和关键结果 低损耗光合路器和分路器是基于 Mach-Zehnder 的光调制器的基本组件,并且是集成电路的关键组成部分。通过在输入/输出波导处使用线性锥形确保输入/输出波导的模式与干涉区域之间的

weixin_45719141的博客 1万+

C#对象拷贝(复制)

C#对象的复制方法

jh_negit的博客 6456

模型量化必知:Per-Tensor和Per-Channel到底怎么选?

本文深入解析了模型量化中Per-Tensor与Per-Channel两种核心策略的抉择。Per-Tensor量化实现简单、硬件兼容性极佳,适合激活值或分布均匀的权重;而Per-Channel量化精度更高,能更好地处理权重分布不均的卷积层,是现代CNN权重量化的主流。文章提供了从硬件平台、数值分布到精度需求的实战决策框架,并推荐了“权重Per-Channel,激活Per-Tensor”的混合量化最佳实践。

assembly8low的博客 983

C# 实现对象的深浅拷贝的三种方式代码示例

面试的时候经常被问到c#对象的深浅拷贝实现以及区别,今天我们就来讲一下深拷贝和浅拷贝到底是什么。首先我们讲讲浅拷贝,浅拷贝就是将对象中的所有字段复制到新对象中去,浅拷贝对于值类型和引用类型有不同的影响。值类型的值被复制到副本中后,修改副本中的值不会影响原来对象的值。然而引用类型的属性被复制到副本中后,再修改副本中的值是会导致原来对象的值被修改的。当然上面说到的引用类型不包含string。那么为什么引用类型修改副本里的值会造成原来对象的值变化而string类型就不会呢?首先我们需要知道string类型实际上是

u010555784的博客 4282

ACM论文LaTeX模板解析(三)| 文章顶部信息(Top matter))Part 1

文章顶部信息(Top matter))Part 1,文章类型、作者信息等

FreshManInC的博客 4853

手把手教你用Sentinel-1和SNAP处理InSAR数据:从下载到生成沉降图(附Python脚本)

本文详细介绍了如何使用Sentinel-1数据和SNAP软件处理InSAR数据,从下载到生成地表沉降图的全流程。通过Python脚本实现自动化处理,适用于城市扩张和地质脆弱带的地表沉降监测,提供高性价比的毫米级形变监测方案。

weixin_26800111的博客 267

C#对象浅拷贝和深拷贝

示例代码 https://github.com/chi8708/DotNetNote/blob/master/Note.Basic/01CopyDemo.cs。浅拷贝是指只拷贝对象的值类型成员,而引用类型成员的引用则保持不变。这意味着新的对象和原始对象将共享所有引用类型成员的实际对象。深拷贝是指不仅拷贝对象的值类型成员,而且还拷贝所有引用类型成员的实际对象。在C#中,对象拷贝是指将一个对象的副本创建到另一个对象中。但是,如果需要避免意外修改原始对象,则应使用深拷贝。C#中的对象深拷贝和浅拷贝。

chi8708的专栏 572

STM32CubeMX | HAL库实战:ADC多通道采集模式深度解析(轮询、DMA、TIM触发)

本文深度解析了基于STM32CubeMX与HAL库实现ADC多通道数据采集的三种核心模式:轮询、DMA以及TIM触发DMA。文章通过对比分析,详细阐述了各模式的配置要点、适用场景与潜在陷阱,旨在帮助开发者根据实时性、CPU占用及采样精度等需求,选择并实现高效稳定的多通道数据采集方案。

postgres8guard的博客 971

理解C#中对象的浅拷贝和深拷贝

本文章主要介绍C#中对象的拷贝,其中包括浅拷贝和深拷贝,以及浅拷贝和深拷贝的实现方式,不同的实现方式之间的性能对比。

风清扬的专栏 1737

设备接入与APP(应用程序)接入华为云iotDA平台的详细操作步骤及获取方式

设备及APP(应用程序) 登录 IoTDA 平台所需的 入场与操作清单内容,提供逐项详细操作步骤和获取方式,并穿插贴士便于理解与实际操作落地。内容基于 华为云 IoTDA 控制台 和 IAM 控制台 的实际使用路径整理。

hy行者勇哥的博客 3059

ABAP RAP 行为建模深入学习:从 Behavior Definition 到 Behavior Implementation 的完整实践指南

ABAP RAP开发指南:业务行为定义与实现 本文介绍SAP RAP框架中业务对象行为的开发方法: 分层设计 Behavior Definition声明业务能力(增删改查、校验、动作等) Behavior Implementation在ABAP类中编写具体逻辑 核心组件 使用BDL定义业务行为 通过FOR BEHAVIOR OF绑定行为池类(ABP) 在本地类实现校验/确定/动作逻辑 关键特性 支持managed/unmanaged两种实现模式 提供草稿表、并发控制等企业级功能 通过EML以别名访问实体 开

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 413

c#对象拷贝

对象的赋值操作相当于引用,xiug

xue251248603的专栏 6261

ardupilot BMI088加速度陀螺仪学习

本节主要记录ardupilot 中BMI088传感器的学习过程,欢迎批评指正。BMI088是一款高性能6轴惯性传感器,由16位数字三轴±24g加速度计和16位数字三轴±2000°/ s陀螺仪组成。 BMI088允许高精度测量方向和沿三个正交轴的运动检测。BMI088具有高振动鲁棒性和3 x 4.5 x0.95mm³的小尺寸,是用于无人机和机器人应用等恶劣环境的高性能IMU中的独特产品。 BMI088专门设计用于有效抑制由于PCB上的共振或整个系统的结构而可能发生的振动。 除了高振动稳定性外,BMI088的出

陌城烟雨 2056

C#对象深拷贝

C#对象深拷贝 众所周知,c#中的对象存在值类型和引用类型之分,故而对象之间的赋值就存在浅拷贝和深拷贝的概念 网上的深拷贝方法也很多,但是要么写的无比复杂,要么有诸多限制 最终还是选择了反射的方法,虽然都说反射效率太低,但是它毕竟最常见最通用的方法 public static T DeepCopy<T>(T obj) { ...

1715

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C#对象拷贝竟然是浅拷贝

C#对象拷贝竟然是浅拷贝,为什么呢?无法容忍! 再次确认为浅拷贝, 使用 = 直接复制对象,为浅拷贝,和python = 一样。

u013965885的专栏 695

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C#中的对象深拷贝和浅拷贝

在C#中,对象拷贝是指将一个对象的副本创建到另一个对象中。对象拷贝通常用于数据传输或创建对象的新实例。C#中有两种主要的拷贝方式:浅拷贝和深拷贝浅拷贝通常用于数据传输,因为它是快速且有效的。但是,如果需要避免意外修改原始对象,则应使用深拷贝。以下是一些有关何时使用浅拷贝和深拷贝的准则:使用浅拷贝:当需要快速创建对象副本时当原始对象不可变时当原始对象和副本不会同时使用时使用深拷贝:当需要避免意外修改原始对象时当原始对象和副本需要同时使用时当原始对象包含引用类型成员时Aigu。

sdgfafg_25的博客 821

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C# 对象的拷贝

C# 对象的拷贝 在程序设计中,我们有时希望得到现有一个对象的拷贝。 拷贝有两种: (1)浅拷贝(也称浅表复制);(2)深拷贝(也称深度复制) 1.浅拷贝 表示将所有非引用数据类型从一个对象复制到另一个对象;如果原有对象包含对像引用,则复制对角引用(即是指当对象的字段值被拷贝时,字段的引用对象不会被拷贝)。形成拷贝后的对象与原对象会引用同一个值。 值的改变:修改副本中的

kendyhj9999的专栏 774

C#中对象的拷贝

前面写了一个java的对象拷贝,所以也写个c#的。其实c#跟java语言的相似度是极高的,所以它们的对象之间的赋值也是相同的,只是不过他们对应的方法不一样。 浅拷贝c#中所提供的浅拷贝方法是object类提供的object MemberwiseClone()。深拷贝当然c#中的深拷贝也可以用java中的方法,每一个类里面都用前拷贝。。。。 c#中也可以用序列化,序列化的方法也是将类对象输入到内存中

angle_sun的博客 895

C#中实现对象的深拷贝

原文:C#中实现对象的深拷贝 深度拷贝指的是将一个引用类型(包含该类型里的引用类型)拷贝一份(在内存中完完全全是两个对象,没有任何引用关系)..........  直接上代码: 1 /// <summary> 2 /// 对象的深度拷贝(序列化的方式) 3 /// </summary> 4 ...

weixin_34128534的博客 267

c#中实现拷贝对象的案例

能不能有更优雅的解决方案。很多人一定很奇怪,之所以会出现这样的问题,就和值类型和引用类型有关,第一个值函数的 string 本身是个值类型,他在存储的时候,是直接开辟了一个存储空间,而第二个data类型的在存储的时候,其实是通过指针将变量和其存储空间链接在了一起,当声明data b=a时,就将b的指针指向了a的指针所指向的存储位置,而当将b.key=“2"赋值后,其实是将b.key所指向的存储空间赋值"2”,这个时候因为a和b的指针是指向同一个存储空间的,所以a.key和b.key的值同时变成了2。

weixin_41883890的博客 2917

C#中如何实现对象拷贝

大家都知道,在C#中变量的存储分为值类型和引用类型两种,而值类型和引用类型在数值变化是产生的后果是不一样的,值类型我们可以轻松实现数值的拷贝,那么引用类型呢,在对象拷贝上存在着一定的难度。 下面我么从一个经典的例子谈起。 private void doChange(string a) { int b = a; b = "2"; System.C...

baodi7426的博客 318

C# 对象属性复制(深拷贝)

记录一个泛型深拷贝方法

SYGODNICE的博客 1355

C#中如何实现对象的深拷贝问题

深拷贝,即实现ICloneable接口.ICloneable可用于深拷贝和浅拷贝 using System;using System.Collections.Generic;public class MyClass{    class InstanceA:ICloneable {  public int x;  public InstanceB B;  public InstanceA(){} 

phphot 2155

C# 对象深拷贝、浅铐贝、直接拷贝

C# 对象深拷贝、浅铐贝、直接拷贝show_ads_zone(203);C#中有两种类型变量,一种是值类型变量,一种是引用类型变量。对于前者,copy是属于全盘复制;而对于后者,一般的copy只是浅copy,相当于只传递一个引用指针一样。因此对于后者进行真正copy的时候,也是最费事的,具体的说,必须为其实现ICloneable接口中提供的Clone方法。浅拷贝(影子克隆):只复制

凌于淳风的专栏 852
上一篇: VsCode Eslint + Vue 自动完善
下一篇: web 打开window应用
BikeRiver
博客等级 码龄10年 11粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值