为什么在C#中引用和退出?

Pra*_*are 15 c#

使用关键字时ref,调用代码需要初始化传递的参数,但是使用关键字out我们不需要这样做.

  • 我们为什么不out到处使用?
  • 这两者之间有什么区别?
  • 请举例说明需要使用ref但不能使用的情况out

Vin*_*jip 16

答案在这篇MSDN文章中给出.从那篇文章:

两个参数传递模式由它们解决out并且ref略有不同,但它们都非常常见.这些模式之间的细微差别导致一些非常常见的编程错误.这些包括:

  1. 不为out 所有控制流路径中的参数赋值
  2. 不将值赋给用作ref参数的变量

因为C#语言为这些不同的参数传递模式分配了不同的明确赋值规则,所以这些常见的编码错误被编译器捕获为不正确的C#代码.

该决定的症结包括refout参数传递模式是允许编译器来检测这些常见的编码错误是值得拥有两个额外的复杂性refout语言中的参数传递模式.


dtb*_*dtb 14

out是一种特殊形式,ref在调用之前不应该初始化引用的内存.

在这种情况下,C#编译器强制out在方法返回之前分配变量,并且在分配变量之前不使用该变量.

两个例子out不起作用但是ref:

void NoOp(out int value) // value must be assigned before method returns
{
}

void Increment(out int value) // value cannot be used before it has been assigned
{
    value = value + 1;
}
Run Code Online (Sandbox Code Playgroud)

  • 此外,调用方法需要在将`ref`参数传递给方法之前初始化它.它可以留下一个"out"参数未初始化.它将被视为在方法调用语句之后初始化. (3认同)

Joh*_*hnB 8

这些答案都没有让我满意,所以这是我的ref对比out.

我的回答是以下两页的摘要:

  1. ref(C#参考)
  2. out(C#参考)

相比

  1. 方法定义和调用方法都必须显式使用ref/ outkeyword
  2. 两个关键字都会导致参数通过引用传递(偶数值类型)
  3. 但是,通过引用传递值类型时没有装箱
  4. 属性不能通过out或传递ref,因为属性确实是方法
  5. ref/ out不被认为是在编译时该方法签名的一部分,从而方法不能被重载如果它们之间的唯一区别是,该方法的一个需要ref的参数和其他需要一个out参数

对比

ref

  1. 必须在传递之前进行初始化
  2. 可以用来将值传递给方法

out

  1. 在传递之前不必初始化
  2. 在方法返回之前,需要调用方法来指定值
  3. 不能用于将值传递给方法

例子

不会编译,因为只有方法签名的差异是ref/ out:

public void Add(out int i) { }
public void Add(ref int i) { }
Run Code Online (Sandbox Code Playgroud)

使用ref关键字:

public void PrintNames(List<string> names)
{
  int index = 0; // initialize first (#1)

  foreach(string name in names)
  {
    IncrementIndex(ref index);
    Console.WriteLine(index.ToString() + ". " + name);
  }
}

public void IncrementIndex(ref int index)
{
  index++; // initial value was passed in (#2)
}
Run Code Online (Sandbox Code Playgroud)

使用out关键字:

public void PrintNames(List<string> names)
{
  foreach(string name in names)
  {
    int index; // not initialized (#1)

    GetIndex(out index);
    Console.WriteLine(index.ToString() + ". " + name);
  }
}

public void GetIndex(out int index)
{
  index = IndexHelper.GetLatestIndex(); // needs to be assigned a value (#2 & #3)
}
Run Code Online (Sandbox Code Playgroud)

作者的随机评论

  1. 在我看来,使用out关键字的概念类似于使用ParameterDirectionOutput枚举值在ADO.NET中声明输出参数
  2. C#中的数组通过引用传递,但为了重新分配数组引用以影响调用代码中的引用,ref必须使用关键字

例:

public void ReassignArray(ref int[] array)
{
  array = new int[10]; // now the array in the calling code
                       // will point to this new object
}
Run Code Online (Sandbox Code Playgroud)

有关引用类型与值类型的更多信息,请参阅传递引用类型参数(C#编程指南)