据我所知,
谢谢。
out
参数的唯一用途是允许调用方从单个方法调用中获取多个返回值。但我们也可以使用ref
参数来获得多个结果值!那么是否存在其他情况下,out
参数可能会证明其有用性并且无法使用ref
参数替代呢?谢谢。
out
参数的唯一用途是允许调用方从单个方法调用中获取多个返回值。但我们也可以使用ref
参数来获得多个结果值!那么是否存在其他情况下,out
参数可能会证明其有用性并且无法使用ref
参数替代呢?是的——ref
和out
之间的区别在于明确赋值:
out
参数在方法调用之前不需要由调用者进行明确的赋值。但是它必须在方法中在正常返回(即没有异常)之前进行明确的赋值。然后该变量在调用者中肯定被赋值了。
ref
参数在方法调用之前必须由调用者进行明确的赋值。但它不需要在方法中分配不同的值。
因此,假设我们希望将int.TryParse(string, out int)
更改为使用ref
。通常调用代码如下:
int value;
if (int.TryParse(text, out value))
{
// Use value
}
else
{
// Do something else
}
现在,如果我们使用ref
,我们需要在调用之前给value
赋一个值,例如:
int value = 0;
if (int.TryParse(text, ref value))
{
// Use value
}
else
{
// Do something else
}
显然这不是一个非常巨大的差异 - 但会给人留下错误的印象。我们正在分配一个我们从来不打算使用的值,这对于可读性来说并不是一件好事。一个out
参数表示一个值将会从方法中输出(假设没有异常),而你不需要有一个值作为输入。
我对C#5提出的一个建议(我不知道是否会被采纳),就是带有out
参数的方法应该被视为返回一个值元组的方法。结合更好的元组支持,这意味着我们可以这样做:
var (ok, value) = int.TryParse(text);
在这种情况下,ok
和 value
将被隐式声明为 bool
和 int
。这样可以清楚地知道什么进入了方法(text
),以及什么是返回值(两个信息:ok
和 value
)。
如果 int.TryParse
使用 ref
参数,那么它将无法使用初始值,因为编译器无法知道是否真正关心 ref
参数的初始值。
Tuple
类型看起来非常琐碎,甚至几乎没有用处。 - stakx - no longer contributingout
参数在你想要从一个方法中获得多个结果值时非常有用。严格来说,你可以使用一个 ref
参数来实现同样的目标,但是 out
参数在传达意图方面做得更好。当你使用 ref
时,不清楚为什么要这样做,而不使用 out
或者使用函数结果。你可能打算改变传递的值,但是从函数签名上并不能清楚地看出为什么要改变它。http://msdn.microsoft.com/en-us/library/f02979c7.aspx
“out”比“ref”更好的主要原因是,在调用之前(甚至是隐式地),你不需要为返回变量分配一个虚拟值。