C# | List.Clear() 和 List = null 产生不同的运行结果

问题:

         在使用 List 时发现一个现象,List.Clear() 和 List=null 会有不一样的运行结果,用一段代码演示一下。

List<int> intSmall= new List<int>() { 1, 2, 3, 4, 5 };
List<List<int>> intLarge = new List<List<int>>();
intLarge.Add(intSmall);

intSmall = null;
//intSmall.Clear();

        预想 intSmall = null 和 intSmall.Clear() 的结果应该是相同的,都是仅清空了 intSmall,intLarge 中的 List 不发生改变,但实际运行结果不同。

        使用 = null 操作时,是预想的结果,intLarge 内的 List 还是保存着“1,2,3,4,5”这五个数字。

        但是,使用 Clear() 操作时,虽然清空的是 intSmall,但 intLarge 中的 List 同样被清空。

原因:

        通过查找一些资料,对该现象的原因进行分析。如有错误,欢迎指正。

        在分析原因之前先明确 List 的两个要点。

1. List 属于“引用类型”

        C#中的类型分为“值类型”和“引用类型”,值类型的存储只需要一段内存,直接存储数据本身,引用类型的存储需要两段内存,一段用于存储数据本身,是存在堆中,另一段是一个引用,指向数据在堆中的位置。

        值类型:

        引用类型:

         而 List 属于引用类型。

2. List.Add() 属于“浅拷贝”

        深拷贝:拷贝对象时,不仅把对象的引用进行拷贝,把对象引用的值也一起拷贝,此时拷贝后的对象和源对象相互独立,对其中任何一个对象的改动都不会影响到另一个对象。

        浅拷贝:拷贝对象时,仅拷贝对象的引用,而拷贝对象和源对象还是引用同一个数据,此时拷贝后的对象和源对象之间存在联系,改变其中任何一个对象都会影响到另一个对象。

        而 List.Add() 属于浅拷贝。

3. 问题的原因

        基于前面两个,对问题原因进行分析。

        intSmall 与内部数据的对应关系如下。

        intLarge.Add(intSmall) 时,进行的是浅拷贝,仅拷贝了 intSmall 的引用。

        此时,如果对 intSmall 进行 Clear,删除的是栈中的数据,因为 intLarge 中的 List 也是指向这些数据,因此 intLarge 中的 List 也为空。

        如果对 intSmall 进行 = null,只是将 intSmall 的引用置为 null,并不会改变该引用所指向的实际数据。因此,此时 intLarge 内的 List 的数据还在。

 参考:

浅复制后list=null和list.clear()区别

List 是一个引用类型

深拷贝和浅拷贝

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值