C# List的赋值问题的解决

 更新时间:2022年07月22日 09:46:20   作者:akhdjkrhyiewbhgj  
本文主要介绍了C# List的赋值问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

问题描述

如下图所示,query1是个集合,把它赋值给了query2,当移除query2里面数据的时候,query1对应的数据也被移除了。

在这里插入图片描述

原因分析:

对此猜测是引用类型的问题,类似于浅拷贝深拷贝那种概念。

基础概念:

对于上述的情况,要怎么去赋值,以及不同的写法对应的结果是什么样的呢,我做了如下测试 ,在看结果之前,先了解一下相关概念。

C#中的堆和栈:(指的是程序运行时的内存区域)

内存分为堆区域和栈区域,栈空间比较小,但是读取速度快(先进后出),堆空间比较大,但是读取速度慢。

栈区:存放函数的参数,局部变量,返回数据等值,会自动释放。

堆区:存放着引用类型的对象,会由GC来自动释放。

值类型和引用类型

值类型:在方法传递的时候,传递的是自身的“拷贝”。
(例如:结构体struct,数据类型short/int/double/bool,枚举类型enum,可空类型)

引用类型:引用类型则是传递的自身的“地址”。
( 例如:数组,类,接口,委托,object,string)

值类型只需要一段单独的内存(此处指栈区内存),用于存储实际的数据。

引用类型需要两段内存,第一段存储实际的数据,位于堆中。第二段是一个引用,存储在栈里,指向数据在堆中的存放位置。

特点:
1、值类型变量声明后,不管是否已经赋值,编译器为其分配内存。
2、引用类型当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new
创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。
3、值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。(某些情况指的是:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上。)
4、引用类型的对象总是在进程堆中分配(动态分配)。

本地测试:

下图展示了4个list以及对应的赋值情况,从结果可以看出,list1、list3、list4的栈区内容都指向了同一个堆地址,所以当这三个list任意一个删除数据或添加数据,其他两个也会变化。而list2由于指向的堆地址跟其他三个不同,所以list2的数据变化不会影响到list1、list3、list4。

在这里插入图片描述

其中list4比较出乎我的意料,印象中list t=new list中的关键字new,会在托管堆上重新分配空间,并返回一个该空间的地址,但是从结果上来看,list4还是指向了list1的堆地址。猜测可能是编译器的自动优化?就像string的赋值那样?

下面是string的测试,图一是定义了三个变量,a、b、c,可以看出,a和b虽然是分别定义并且分别赋值的,但由于值一样,最终还是指向了同一个堆地址。而图二中,给a重新赋值后,发现它并没有去更改原地址中的数据,而是在堆中开辟了一块新的空间,并指向了这个新的堆地址(在栈中的地址没变)。

在这里插入图片描述

在这里插入图片描述

 到此这篇关于C# List的赋值问题的解决的文章就介绍到这了,更多相关C# List赋值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#设置或验证PDF文本域格式的方法详解

    C#设置或验证PDF文本域格式的方法详解

    PDF中的文本域可以通过设置不同格式,用于显示数字、货币、日期、时间、邮政编码、电话号码和社保号等等。本文将介绍如何通过C#设置或验证PDF文本域格式,需要的可以参考一下
    2022-01-01
  • C#多线程系列之手动线程通知

    C#多线程系列之手动线程通知

    本文详细讲解了C#多线程中的手动线程通知,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • unity实现简单计算器

    unity实现简单计算器

    这篇文章主要为大家详细介绍了unity实现简单计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Unity 实现删除missing脚本组件

    Unity 实现删除missing脚本组件

    这篇文章主要介绍了Unity 删除missing脚本组件的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • c#使用linq技术创建xml文件的小例子

    c#使用linq技术创建xml文件的小例子

    c#使用linq技术创建xml文件的小例子,需要的朋友可以参考一下
    2013-03-03
  • C#实现DevExpress本地化实例详解

    C#实现DevExpress本地化实例详解

    这篇文章主要介绍了C#实现DevExpress本地化,以实例形式较为详细的分析了DevExpress本地化的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • C#自定义简化cookie类实例

    C#自定义简化cookie类实例

    这篇文章主要介绍了C#自定义简化cookie类,实例分析了C#操作cookie的添加、获取及删除等操作的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • C#实现客户端弹出消息框封装类实例

    C#实现客户端弹出消息框封装类实例

    这篇文章主要介绍了C#实现客户端弹出消息框封装类,实例分析了C#弹出窗口的实现技巧,非常具有实用价值,需要的朋友可以参考下
    2015-03-03
  • c#常用表格控件dataGridView的分页显示

    c#常用表格控件dataGridView的分页显示

    最近项目需要自己写了一个用来给DataGridView分页用的控件,下面这篇文章主要给大家介绍了关于c#常用表格控件dataGridView的分页显示,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • c# rsa加密解密详解

    c# rsa加密解密详解

    这篇文章主要介绍了c# rsa加密解密的的相关资料,文中代码非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06

最新评论