通过引用传递数组元素

本文关键字:数组元素 引用 | 更新日期: 2023-09-27 18:11:48

可能重复:
通过引用和.net垃圾回收的C#参数

我正在考虑使用ref参数来限制数组的边界检查。例如,交换两个元素的代码是:

class Test {
  int[] array;
  private void qSort() {
    ...blah...
    int temp = array[a];
    array[a] = array[b];
    array[b] = temp;
  }
}

它有4个访问阵列的权限替代方案是:

class Test {
  int[] array;
  private void qSort() {
  ...blah...
    Swap( ref array[a], ref array[b] );
  }
  static void Swap(ref int a,ref int b) {
    int temp = a;
    a=b;
    GC.Collect();  // suppose this happens
    b=temp;
  }
}

理论上只有2次访问阵列

让我困惑的是,当我通过引用传递数组元素时,我不知道会发生什么。如果垃圾回收器在执行Swap函数中的代码时启动,它将能够移动数组吗?或者数组在调用期间被固定?

请注意,上面的代码只是一个简单的测试用例。我想在更复杂的场景中使用它

编辑:正如BrokenGlass所指出的,这是Eric Lippert通过引用C#参数和.net垃圾收集来回答的

数组将不会被固定,GCollector可以移动它,并将根据对其元素的任何引用进行更新,该元素位于堆栈

通过引用传递数组元素

Swap函数仍然访问数组3或4次,Swap函数与更简单的代码相比没有提供任何性能优势。如果重复使用,它可能会很有用。

static void Swap(ref int a, ref int b) 
{     
    int temp = a;  //<-- Here, a is in the array
    a=b;           //<-- a and b are in the array
    b=temp;        //<-- b is in the array
}

垃圾收集器不会释放您有引用的内存,就像您通过引用传递时一样。

堆栈可能如下所示:

  • qSort((具有对数组的引用
  • Swap((

因此,如果GC.Collect((在交换中执行,那么qSort((中仍然有对数组的引用,这意味着它不会被收集。