什么情况下是“out”?参数有用(不能使用“ref”来代替)?
据我所知,out 参数的唯一用途是调用者可以从单个方法调用中获取多个返回值。但我们也可以使用 ref 参数来获取多个结果值!
那么是否还有其他情况下 out
参数可能有用,而我们不能使用 ref
参数呢?
谢谢。
As far as I can tell, the only use for out
parameters is that a caller can obtain multiple return values from a single method invocation. But we can also obtain multiple result values using ref
parameters instead!
So are there other situations where out
parameters could prove useful and where we couldn't use ref
parameters instead?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的 -
ref
和out
之间的区别在于明确赋值:out
参数不会 必须在方法调用之前由调用者明确分配。它确实必须在方法正常返回之前(即没有异常)在方法中明确赋值。然后,该变量在调用之后在调用者中明确分配。ref
参数确实必须在方法调用之前由调用者明确分配。它不必在方法中被分配不同的值。因此,假设我们想将
int.TryParse(string, out int)
更改为使用ref
。通常调用代码如下所示:现在如果我们使用
ref
,我们必须在调用之前给value
一个值,例如:显然它不是巨大的差异 - 但它给人错误的印象。我们分配了一个我们无意使用的值,这对于可读性来说并不是一件好事。
out
参数表示一个值将会从该方法中出来(假设没有例外),并且您不需要从一个值开始。我对 C# 5 提出的一个建议(我不知道它是否会被采纳)是带有
out
参数的方法应该能够被视为一个方法返回值的元组。结合对元组的更好支持,这意味着我们可以这样做:在这种情况下,
ok
和value
将隐式键入为bool
和int
分别。这样就可以清楚地知道方法中的内容(text
)和输出的内容(两条信息:ok
和value
)。如果
int.TryParse
使用ref
参数,那么这根本不可用 - 因为编译器无法知道它是否会实际上关心关于ref
参数的初始值。Yes - the difference between
ref
andout
is in terms of definite assignment:An
out
parameter doesn't have to be definitely assigned by the caller before the method call. It does have to be definitely assigned in the method before it returns normally (i.e. without an exception). The variable is then definitely assigned in the caller after the call.A
ref
parameter does have to be definitely assigned by the caller before the method call. It doesn't have to be assigned a different value in the method.So suppose we wanted to change
int.TryParse(string, out int)
to useref
instead. Usually the calling code looks like this:Now if we used
ref
, we'd have to givevalue
a value before the call, e.g.:Obviously it's not a huge difference - but it gives the wrong impression. We're assigning a value that we have no intention of ever using, and that's not a good thing for readability. An
out
parameter indicates that a value will come out of the method (assuming there's no exception) and that you don't need to have a value to start with.Once of the suggestions I've made for C# 5 (I've no idea if it'll be taken up or not) is that a method with an
out
parameter should be able to regarded as a method returning a tuple of values. Combined with better support for tuples, that would mean we could do something like this:In this case
ok
andvalue
would be implicitly typed tobool
andint
respectively. That way it's clear what's going into the method (text
) and what's coming out (two pieces of information:ok
andvalue
).That would simply not be available if
int.TryParse
used aref
parameter instead - as the compiler can't know whether it's going to actually care about the initial value of theref
parameter.您可以这样看待参数:
普通参数在参数中:
值可以通过这样的参数进入函数;
ref
参数是in-out 参数:值可以通过这样的参数进入和离开函数。由于前者,它也必须被初始化。
out
参数是 out 参数:值只能通过这样的参数从函数返回;因此,它不需要初始化。
我通过研究微软的COM技术想出了这种查看
ref
/out
参数的方法。 IDL(接口描述语言)用于描述 COM 组件接口,通过 IDL,参数可以用in
、out
和inout
声明符来扩充。我怀疑 .NET 和 C# 部分地从 COM 继承了这些声明符,尽管名称略有不同(ref
而不是inout
)。对于 COM,
out
参数经常用于检索接口方法的实际返回值,因为“真实”返回值通常已用于返回HRESULT
成功/错误代码。对于 .NET,我认为
out
参数的重要性要低得多,即使您想从方法返回多个值(您可以返回复杂的对象或Tuple
)这些情况)。You can look at parameters in this way:
normal parameters are in parameters:
A value can go into the function through such a parameter; therefore it must be initialized.
ref
parameters are in-out parameters:A value can go into and out of a function through such a parameter. Because of the former, it must also be initialized.
out
parameters are out parameters:A value is only supposed to come back from a function through such a parameter; therefore, it doesn't need to be initialized.
I came up with this way of looking at
ref
/out
parameters by studying Microsoft's COM technology. IDL (interface description language) is used to describe COM component interfaces, and with IDL, parameters are augmented within
,out
, andinout
declarators. I suspect .NET and C# have partly inherited these declarators from COM, albeit with slightly different names (ref
instead ofinout
).With COM,
out
parameters are frequently used to retrieve an interface method's actual return value, since the "real" return value is often already used for returning aHRESULT
success/error code.With .NET, I think
out
parameters have far less importance, even in cases where you want to return several values from a method (you could return complex objects orTuple
s in these situations).一个重要的区别是:
(ref 参数不需要此)
来源:http: //msdn.microsoft.com/en-us/library/t3c3bfhx(VS.71).aspx
One important difference is this:
(A ref parameter does not require this)
Source: http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.71).aspx
当您想要从方法中获得多个结果值时,
out
参数非常有用。从技术上讲,您可以使用ref
参数来实现相同的目标,但out
参数在传达意图方面效果明显更好。当您使用ref
时,不清楚为什么要这样做而不是使用out
或而不是使用函数结果。据推测,您打算更改传递的值,但仅从函数签名中并不清楚为什么要更改它。An
out
parameter is useful when you want multiple result values from a method. Technically, you could use aref
parameter to achieve the same goal but anout
parameter does a significantly better job at conveying intent. When you useref
, It is not clear why you are doing so instead of usingout
or instead of using the function result. Presumably, you intend on changing the value passed, but why you are changing it isn't clear simply from the function signature.我认为一个很好的例子是 int.TryParse()
http://msdn.microsoft .com/en-us/library/f02979c7.aspx
out 优于 ref 的主要原因是您不需要分配虚拟值在调用之前将值赋给 return var(甚至是隐式的)。
所以 out 告诉你和编译器:“这个 var 将在方法内赋值。并且 var 的初始值(如果有)甚至不会被查看。”
I think a fine example is int.TryParse()
http://msdn.microsoft.com/en-us/library/f02979c7.aspx
The primary reason that out is better than ref is that you don't need to assign a dummy value to the return var before calling (even implicitly).
So out tells you, and the compiler: "This var will be assigned within the method. And the var's initial value, if any, will not even be looked at."
两者之间的主要区别在于,如果我们使用 ref ,那么我们必须在调用之前对其进行初始化,并且可以选择在方法中为 ref 变量赋值。
然而,对于 out 方法,我们不必显式初始化它们,但在我们的方法中,我们必须为其分配一些值,否则它们将生成编译时错误。
Major difference between the two is that if we are using ref then we have to initialize this before call and it is optional that we assign a value to our ref variable in our method.
However for out methods we do not have to explicitly initialize them but in our method we have to assign some value to it, otherwise they will generate compile time error.