使用关键字 ref
时,调用代码需要初始化传递的参数,但使用关键字 out
,我们不需要这样做。
out
?ref
并且无法使用 out
?答案 0 :(得分:16)
答案在MSDN article中给出。从那篇文章:
两个参数传递模式 由
out
和ref
处理的是巧妙的 不同,但他们都非常 共同。微妙的区别 这些模式导致一些非常普遍 编程错误。其中包括:
- 没有为
out
分配值 所有控制流路径中的参数- 不为变量赋值 用作
醇>ref
参数因为C#语言分配 不同的明确分配规则 这些不同的参数传递 模式,这些常见的编码错误 被编译器捕获为 不正确的C#代码。
决定包括的关键
ref
和out
参数传递 模式是允许编译器 检测这些常见的编码错误 值得额外的复杂性 同时拥有ref
和out
参数 用语言传递模式。
答案 1 :(得分: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;
}
答案 2 :(得分:8)
这些答案都没有让我满意,所以这是我对ref
与out
的看法。
我的回答是以下两页的摘要:
<强>比较强>
ref
/ out
关键字out
或ref
传递属性,因为属性确实是方法ref
/ out
在编译时不被视为方法签名的一部分,因此如果方法之间的唯一区别是方法之一采用{{1},则方法不能重载参数和另一个采用ref
参数<强>对比度强>
out
ref
<强>实施例强>
无法编译,因为只有方法签名的差异为out
/ ref
:
out
使用public void Add(out int i) { }
public void Add(ref int i) { }
关键字:
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)
}
关键字:
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)
}
关键字的概念类似于使用out
枚举值ParameterDirection在ADO.NET中声明输出参数Output
关键字示例:
ref
有关参考类型与价值类型的详情,请参阅Passing Reference-Type Parameters (C# Programming Guide)
答案 3 :(得分:1)
当你需要使用ref而不是out时,一个人为的例子如下:
public void SquareThisNumber(ref int number)
{
number = number * number;
}
int number = 4;
SquareThisNumber(ref number);
我们希望number
成为输入输出变量,因此我们使用ref
。如果我们使用了out
,那么编译器会在使用之前初始化out
参数时给出错误。
答案 4 :(得分:1)
ref关键字允许您更改参数的值。被调用的方法可以是调用链中的中间链接。使用out关键字的方法只能在调用链的开头使用。
另一个优点是现有值可以在方法的逻辑中使用,并且仍然保持返回值。
在Oracle函数中有显式的IN(默认值以及未设置方向时获得的内容)IN / OUT和OUT参数。等效是正常的(只是参数),ref [参数]和out [参数]。
答案 5 :(得分:0)
编译器知道在调用之前不应设置out变量。这允许它们在使用前声明。但是它知道它必须在返回时使用的函数之前设置。
答案 6 :(得分:0)
当我们在调用前缀为out
关键字的方法时传递值时,它会将它视为完全不同,就像我们没有将它传递给方法一样。相反,我们实际上是从out方法的定义部分收集(outing)out变量的值到我们调用该方法的method out变量参数。
所以out variable
是在方法定义中完成的处理的输出,这就是我们需要创建它,初始化它并仅在定义中修改它的原因。
当我们需要从特定方法返回多个值时,使用out
变量。
在ref
变量的情况下,我们需要首先初始化它,因为它的内存位置被转换为方法定义作为参数。想想如果我们在传递之前没有初始化它会发生什么?