假设我写数组的第二个元素发生了什么?
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
这是如何工作的?我是否奇迹般地将numbers[1]
作为托管堆上单独的可寻址编号进行分配?这里发生了什么?
假设我写数组的第二个元素发生了什么?
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
这是如何工作的?我是否奇迹般地将numbers[1]
作为托管堆上单独的可寻址编号进行分配?这里发生了什么?
Array.Resize
创建新的数组,留下在堆上的旧的,如每the documentation:
此方法分配一个新的数组具有指定大小, 将元素从旧数组复制到新数组,然后用新数组替换旧数组。
(我的重点)
注意:文档取决于你如何理解它有些误导。它说“然后用新的替换旧的阵列”。这意味着它将取代参考您在示例中的数组变量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));
}
}
此输出:
2 // the new array, which did not change
100 // the original array, which did change
false // not the same arrays
所以ref int
变量的确发生了变化,原来阵列做变化,但新的,大小修改,复制没有。
此方法分配一个具有指定大小的新数组,将元素从旧数组复制到新数组,然后用新数组替换旧数组。数组必须是一维数组。
如果array为null,则此方法将创建一个具有指定大小的新数组。
如果newSize大于旧数组的长度,则会分配一个新数组,并将所有元素从旧数组复制到新数组。如果newSize小于旧数组的长度,则会分配一个新数组,并将元素从旧数组复制到新数组,直到新数组被填充;旧数组中的其余元素将被忽略。如果newSize等于旧数组的长度,则此方法不执行任何操作。
直从MSDN
我不明白你的问题在这里?你只是使用指针? – Seth
我把他的问题的意思是“这里发生了什么'ref int second''因为他的数组现在只包含'[0]'索引,所以'ref int second'仍然工作,因为它指向'[[ 1]元素。 –