博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# List 赋值(一) --引用类型的赋值和复制
阅读量:5222 次
发布时间:2019-06-14

本文共 2520 字,大约阅读时间需要 8 分钟。

最近项目维护中遇到一个问题,确切的说应该是两个月前的问题也是因为这里引起的,可惜当时困于业务不熟悉,也没有更多时间允许查询根源,导致再次引发了新的问题!!!

问题场景:基础数据存于List类型的BOMs中,计算过程是对List类型的normalBoms和configBoms变量传值后,normalBoms和configBoms进行计算,发现

对configBoms的操作会修改基础数据BOMs中的值!!!

起初就考虑到是因为List类型是引用类型,所以传值会修改原值,但是normalBoms的值没有同步被修改,所以详细比较两个变量的传值逻辑:

 

1             static List
BOMs = new List
(); 2 static void Main(string[] args) 3 { 4 for (int i = 0; i < 10; i++) 5 { 6 BOMs.Add(i); 7 } 8 9 List
normalBoms = null;10 List
configBoms = null;11 12 normalBoms = GetNormalBoms();13 configBoms = GetConfigBoms();14 15 configBoms[9] = 19;16 17 }18 static List
GetNormalBoms()19 {20 List
boms = new List
();21 //...22 foreach (int bom in boms)23 {24 //...25 boms.Add(bom);26 }27 //......28 return boms;29 }30 31 static List
GetConfigBoms()32 {33 List
boms = null;34 //......35 boms = BOMs;36 //......37 return boms;38 }

 注意:GetNormalBoms()方法中行22和方法GetConfigBoms()方法中行35的差异,所以猜测(因为没有认真考虑)是没有进行new操作(new会分配新的内存),最终导致configBoms还是只想BOMs的同一个内存,即发放返回了一个引用,后续对configBoms的操作也会影响BOMs,作出相应修改:

行10List<int> configBoms = null; 修改为 List<int> configBoms = new List<int>(); ,(分配了内存,configBoms是指向新的内存的)

最终运行,发现后续对configBoms的操作还是会影响BOMs,更加详细的思考为什么???

这里就开始认真回想之前对引用类型的理解,因为常有查看值类型和引用类型的区别,现在是理论和实践的结合了:

首先,理解引用类型的变量存储的是内存的地址(对象的引用),即对象的数据在托管堆中,变量中的引用在栈上(借鉴:)

其次,引用类型的变量赋值传递的是对象的应用,也就是变量赋值的是内存的地址,所以赋值后多个变量指向了同一个对象实例

基于以上两点,代码中问题不难解释了:虽然configBoms通过new操作分配了新的内存(此时新分配的内存记为mom1,原来BOMs指向的内存mom0),但是后续的赋值操作configBoms=GetConfigBoms()中没有修改内存指向,所以赋值操作是变量configBoms的值,即configBoms中的地址不在指向mom1,而是指向了mom0,此时的configBoms是mom0存储的对象实例的一个引用,和BOMs等同,所以修改configBoms会影响BOMs。(:内存mom1并没有消失,只是configBoms不在指向mom1,也不能通过configBoms修改mom1的内容)

但是反观方法GetNormalBoms()方法,方法中先通过new分配了行的内存(记为mom2),然后为新的变脸赋值是通过Add方法,是在新的内存mom2中增加数据,变量中的地址没有变,所以normalBoms变量还是指向mom2的,与configBoms和BOMs不同。

了解了原理,那么解决我的问题的方法就是:在给configBoms传值时,不能只修改变量值,而是要分配新内存,数据要赋值进新内存中

List的复制(借鉴:)

因为考虑到实际项目中,不是循环都合适,同时现有代码结构不易修改,不通过类似GetNormalBoms()的方法给configBoms赋值,通过new List<int>(BOMs)进行赋值,即:

行13修改为 configBoms = new List<int>(GetConfigBoms()); 

问题最终是解决了。所以学以致用,细致入微,真的是很基础的内容,以前只知道概念,现在真正才是开始将学习的知识运用到实践中来。

 

转载于:https://www.cnblogs.com/jie0602/p/9427041.html

你可能感兴趣的文章
session token两种登陆方式
查看>>
IntelliJ IDEA 12集成Tomcat 运行Web项目
查看>>
java,多线程实现
查看>>
个人作业4-alpha阶段个人总结
查看>>
android smack MultiUserChat.getHostedRooms( NullPointerException)
查看>>
递归-下楼梯
查看>>
实用的VMware虚拟机使用技巧十一例
查看>>
监控工具之---Prometheus 安装详解(三)
查看>>
不错的MVC文章
查看>>
网络管理相关函数
查看>>
IOS Google语音识别更新啦!!!
查看>>
20190422 T-SQL 触发器
查看>>
[置顶] Linux终端中使用上一命令减少键盘输入
查看>>
poj1422_有向图最小路径覆盖数
查看>>
BootScrap
查看>>
[大牛翻译系列]Hadoop(16)MapReduce 性能调优:优化数据序列化
查看>>
WEB_点击一百万次
查看>>
CodeForces - 878A Short Program(位运算)
查看>>
路冉的JavaScript学习笔记-2015年1月23日
查看>>
Mysql出现(10061)错误提示的暴力解决办法
查看>>