假设我写
int numbers[] = {1,2,3};
ref int second = ref numbers[1];
Array.Resize(ref numbers, 1);
Console.WriteLine(second); // works fine
second = 321; // also legit
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?我是否numbers[1]
在托管堆上神奇地分配为单独的可寻址号码?这里发生了什么?
Array.Resize
根据文档创建一个新数组,将旧数组保留在堆上:
此方法分配具有指定大小的新数组,将旧数组中的元素复制到新数组,然后用新数组替换旧数组.
(我的重点)
注意:根据您的理解,文档会略有误导.它说"然后用新的阵列取代旧阵列".它的意思是,它取代了引用您在数组变量有,numbers
在你的榜样,与新的数组的引用.旧的数组对象保持原样并且在内存中不受影响.
如果你没有ref int
引用它,GC最终会把它拿起来,但是既然你这样做了,它就不会.
second = 321
更改原始数组,而不是新数组.
您可以使用一个非常简单的示例轻松显示:
using System;
public class Program
{
public static void Main()
{
int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] b = a;
ref int a1 = ref a[1];
Array.Resize(ref a, 5);
a1 = 100;
Console.WriteLine(a[1]); // new
Console.WriteLine(b[1]); // original
Console.WriteLine(ReferenceEquals(a, b));
}
}
Run Code Online (Sandbox Code Playgroud)
这输出:
2 // the new array, which did not change
100 // the original array, which did change
false // not the same arrays
Run Code Online (Sandbox Code Playgroud)
所以ref int
变量确实发生了变化,原始数组确实发生了变化,但新的,经过尺寸修改的副本却没有.
归档时间: |
|
查看次数: |
62 次 |
最近记录: |