记录一下C#深拷贝的几种方式

这篇具有很好参考价值的文章主要介绍了记录一下C#深拷贝的几种方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、C#中预定义数据类型

        1》值类型

         2》引用类型

两种类型的不同点:

       概念:值类型直接存储其值,而引用类型存储对值的引用

       存储:值类型存储在堆栈(stack)上,而引用类型存储在托管堆上(managed heap)。

当使用值类型,进行赋值的操作时,将1个变量的值赋值给另外1个变量,例如

int x = 10;
int y = x; 
y = 20;

这表示上面的语句会在内存中的两个地方存储值10。这样直接更改y变量的值时,不会影响到x的值。

当使用引用类型,进行赋值的操作时,例如

List<int>  listNum = new List<int>();
listNum.add(1);
listNum.add(2);
listNum.add(3);
List<int> listNum1 = listNum;
listNum.Clear();
listNum.Count;
listNum1.Count;

当我们访问两个变量的数量时,都为0。

记录一下C#深拷贝的几种方式

       首先,listNum和listNum1,都是引用类型的变量,它们都指向包含该内存的位置,引用类型变量的赋值,只保留了一个引用,因为两个变量都指向了一块内存地址,所以对两个变量中任何一个变量的操作都会影响到另外一个。

那么该怎么办呢?我们可以通过深拷贝的方式解决上面的问题。

通过以下几种方式,实现深拷贝。

1、最简单直接的是,循环变量赋值

private static List<int> DeepCopyData(List<int> list)
{
    //此处使用new关键字,创建了对象,所以该变量指向了个新的引用
    List<int> listDeep = new List<int>();
    for(var i=0;i<list.Count;i++)
    {
        var item = list[i];
        listDeep.Add(item);
    }
    return listDeep;
}

 因为在函数体中,直接创建了新的对象,在进行其他操作,就不会影响另外一个变量了。

2、通过JsonConvert,序列化和反序列化操作

 public static T DeepCopyJson<T>(T obj)
 {
     // 序列化
     string json = JsonConvert.SerializeObject(obj);
     // 反序列化
     return JsonConvert.DeserializeObject<T>(json);
 }

 3、通过XmlSerializer和内存流

private static T DeepCopyXml<T>(T obj)
{
     object rel;
     using (MemoryStream ms = new MemoryStream())
      {
          XmlSerializer xml = new XmlSerializer(typeof(T));
          xml.Serialize(ms, obj);
          ms.Seek(0, SeekOrigin.Begin);
          rel = xml.Deserialize(ms);
          ms.Close();
      }
      return (T)rel;
}

4、通过BinaryFormatter和内存流

private static T DeepCopyBinary<T>(T obj)
{
     object rel;
     using (MemoryStream ms = new MemoryStream())
     {
          BinaryFormatter bf = new BinaryFormatter();
          bf.Serialize(ms, obj);
          ms.Seek(0, SeekOrigin.Begin);
          rel = bf.Deserialize(ms);
          ms.Close();
     }
     return (T)rel;
}

5、通过DataContractSerializer和内存流文章来源地址https://www.toymoban.com/news/detail-404426.html

private static T DeepCopyDataContract<T>(T obj)
{
     object rel;
     using(MemoryStream ms = new MemoryStream())
     {
          DataContractSerializer ser = new DataContractSerializer(typeof(T));
          ser.WriteObject(ms, obj);
          ms.Seek(0, SeekOrigin.Begin);
          rel = ser.ReadObject(ms);
          ms.Close();
     }
     return (T)rel;
}

到了这里,关于记录一下C#深拷贝的几种方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录--盘点前端实现文件下载的几种方式

    前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。 通过 a 标签的 download 属性来实现文件下载,这种方式是最简单的,也是我们比较常用的方式,先来看示例代码: 就上面的这个示例,我们点击下

    2024年02月13日
    浏览(54)
  • 结构体声明、定义和初始化的几种方式

    五种结构体声明方式: 直接声明结构体类型 声明结构体类型的同时定义结构体变量 不指定结构体名而直接定义结构体变量 使用结构体标记和类型别名 直接声明结构体别名 在C语言中,标记(tag)是在定义struct, union或enum之后使用的标识符。 之所以称其为结构体的“

    2023年04月11日
    浏览(46)
  • C# 常用Excel导出的几种常见方式及实现步骤

    目录 常用Excel导出方式 1.使用 Microsoft Office Interop Excel 组件导出 Excel 文件 2.使用 NPOI 组件导出 Excel 文件  3.使用 EPPlus 组件导出Excel文件 4. 使用 ClosedXML 组件导出 Excel 文件 在 C# 中,常用的Excel 文件导出 方式包括: 使用 Microsoft Office Interop Excel 组件:这是一种使用 Microsoft E

    2024年02月06日
    浏览(80)
  • C#面:列举ASP.NET页面之间传递值的几种方式

    查询字符串(Query String): 可以通过在URL中添加参数来传递值。 例如:http://example.com/page.aspx?id=123 在接收页面中可以通过Request.QueryString[“id”]来获取传递的值。 会话状态(Session State): 可以使用Session对象在不同页面之间存储和检索值。 在发送页面中可以使用Session[“k

    2024年02月19日
    浏览(46)
  • Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化

    1.类什么时候被加载到JVM中,new,Class.forName: Class.forName(“包名.类名”); 2.创建对象的方式,反射,本质是获得类的类对象Class; 3.克隆clone,深拷贝,浅拷贝的对比; 4.序列化和反序列化的方式; Hello h; // 此时没有用Hello,jvm并没有进行类加载 看到new : new Book() Class.forName:

    2024年02月12日
    浏览(44)
  • 17、YML配置文件及让springboot启动时加载我们自定义的yml配置文件的几种方式

    其实本质和.properties文件的是一样的。 Spring Boot默认使用SnakeYml工具来处理YAML配置文件,SnakeYml工具默认就会被spring-boot-starter导入,因此无需开发者做任何额外配置。 YAML本质是JSON的超级,它在表示结构化文档时更有表现力。 ▲ properties文件使用 .分隔符 作为结构化的表现:

    2024年02月14日
    浏览(48)
  • JS实现深拷贝的几种方法

    这是最简单的方法。 通过递归的方式深度遍历对象,将每个属性的值进行复制。需要处理被复制对象为值类型的情况以及属性值中包含对象的情况。需要注意的是,为了防止循环引用导致死循环,需要记录已经遍历过的对象。 Lodash Lodash 是一个一致性、模块化、高性能的 J

    2024年02月11日
    浏览(54)
  • 35、解释一下spring支持的几种bean的作用域

    singleton: 默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。该对象的生命周期是与Spring IOC容器一致的 (但在第一次被注入时才会创建)。 prototype:为每一个bean请求提供一个实例。在每次注入时都会创建一个新的对象· request: bean被定义为在每个HTTP请求中

    2024年02月16日
    浏览(44)
  • Redis 常见的几种数据结构说一下?各自的使用场景?

    介绍:string 数据结构是简单的 key-value 类型。 使用场景: 一般常用在需要计数的场景,比如用户的访问次数、热点文章的点赞转发数量等等。 介绍:list 即是 链表 使用场景:发布与订阅或者说消息队列、慢查询。 介绍:hash 类似于 JDK1.8 前的 HashMap,内部实现也差不多(数组

    2024年01月24日
    浏览(46)
  • Python入门【变量的作用域(全局变量和局部变量)、参数的传递、浅拷贝和深拷贝、参数的几种类型 】(十一)

     👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🔥如果感觉博主的文章还不错

    2024年02月15日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包