【问题标题】:Why would ref be used for array parameters in C#?为什么 ref 将用于 C# 中的数组参数?
【发布时间】:2013-10-15 22:18:31
【问题描述】:

我阅读了页面 Passing Arrays Using ref and out (C# Programming Guide) 并想知道为什么我们需要将数组参数定义为 ref 参数,而它已经是一个引用类型。被调用函数的变化不会反映在调用函数中吗?

【问题讨论】:

  • 是的,他们会的,这就是使用ref的原因。
  • 既然更改会被反映,那还不够,而不是显式使用 ref

标签: c# out ref


【解决方案1】:

被调用函数的变化不会反映在调用函数中吗?

对数组的内容的更改将反映在调用者方法中 - 但对参数本身的更改不会。比如:

public void Foo(int[] x)
{
    // The effect of this line is visible to the caller
    x[0] = 10;

    // This line is pointless
    x = new int[] { 20 };
}
...
int[] original = new int[10];
Foo(original);
Console.WriteLine(original[0]); // Prints 10

现在,如果我们将 Foo 更改为具有以下签名:

public void Foo(ref int[] x)

并将调用代码更改为:

Foo(ref original);

然后它会打印 20。

理解一个变量和它的值所指的对象之间的区别是非常重要的——同样地,修改一个对象和修改一个变量

更多信息请查看我的article on parameter passing in C#

【讨论】:

  • 详细说明...对于数组,如果不创建全新的数组,传统上您无法修改大小。所以当你想用一个新数组替换它时,你可能想使用 ref 或 out 关键字来有效地改变大小。
  • @TrevorElliott:除了它当然不会真正“替换数组” - 它会更改引用数组并用作参数的单个变量的值。任何引用原始数组的其他变量将仍然引用原始数组。
  • 是的,这就是为什么这通常不是一个好主意,如果您需要动态大小的集合,为什么使用 List 是一个更好的选择。
  • BCL 确实提供了这种调整大小的理念:Array.Resize(ref x, 10);x 更改为例如长度为 10 的新实例 int[];见Resize
  • Array.Resize 的问题在于,与列表相比,它的处理时间非常昂贵。
【解决方案2】:

如果您只打算更改数组的内容,那么您是正确的。但是,如果您打算更改数组本身,则必须通过引用传递。

例如:

void foo(int[] array)
{
  array[0] = 5;
}

void bar(int[] array)
{
  array = new int[5];
  array[0] = 6;
}

void barWithRef(ref int[] array)
{
  array = new int[6];
  array[0] = 6;
}


void Main()
{
  int[] array = int[5];
  array[0] = 1;

  // First, lets call the foo() function.
  // This does exactly as you would expect... it will
  // change the first element to 5.
  foo(array);

  Console.WriteLine(array[0]); // yields 5

  // Now lets call the bar() function.
  // This will change the array in bar(), but not here.
  bar(array);

  Console.WriteLine(array[0]); // yields 1.  The array we have here was never changed.

  // Finally, lets use the ref keyword.
  barWithRef(ref array);

  Console.WriteLine(array[0]); // yields 5.  And the array's length is now 6.
}

【讨论】:

  • “Jon 在正确答案上打败了我。该死!我是 Jack 伤心的心。”
  • 我知道已经很久了,但这个答案让我感到困惑。当您调用 bar() 时,它应该返回 5(而不是 1),对吗?因为你已经通过 foo() 修改了数组
猜你喜欢
  • 2017-10-20
  • 2011-02-21
  • 2010-10-06
  • 2010-11-23
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 2013-07-29
相关资源
最近更新 更多