为什么未用ref传递的数组,在方法内调用CopyTo后原数组会被修改?
核心原理
C# 中数组属于引用类型,不带ref关键字传递参数时,传递的是「原引用的副本」——也就是说方法内的nums变量和调用方的arr变量是两个独立的变量,但一开始它们指向堆内存中同一个数组对象。
两种写法的本质差异是:
1. 直接对nums赋值的情况
nums = tail.Concat(nums).Take(nums.Length).ToArray();
这个操作修改的是方法内nums这个引用变量本身的值:让这个局部的引用副本指向了新生成的另一个数组对象,完全不会影响调用方arr变量的指向,也不会修改原来的数组对象,所以外部看不到变化。
2. 调用CopyTo的情况
xxx.ToArray().CopyTo(nums, 0);
这个操作全程没有修改nums这个引用变量本身的指向,而是顺着nums引用找到它指向的原数组对象,直接修改该对象内部的元素值。由于调用方的arr和方法内的nums一开始就指向同一个堆对象,所以外部访问arr时自然能看到修改后的结果。
通俗类比
你可以把引用理解为写着房屋地址的纸条:
- 不带
ref传参相当于你把地址抄了一份给别人:别人把他手里的纸条上的地址改成别的房子,对你手里的纸条没有任何影响,对应第一种赋值的情况。 - 别人拿着抄来的地址找到房子,把房子里的家具全部换掉,你按照自己手里的地址去找房子,看到的自然是换过家具的房子,对应
CopyTo修改对象内部内容的情况。
如果加了ref关键字,就相当于你直接把自己手里的地址纸条交给别人,别人直接修改这张纸条上的内容,你手里的地址也会跟着变,这时候对参数的赋值才会修改外部引用的指向。
内容的提问来源于stack exchange,提问作者bryukva
相关产品推荐
相关产品推荐

