为什么在C#中必须指定"out"关键字?

3
在我提出问题之前,请看一下这个示例函数:
DateTime.TryParse("01/01/2000", out oDate)

为什么我需要指定out关键字?编译器不应该从函数的定义中知道吗?

我出于好奇问这个问题,希望能对编译器有更深入的了解。

同时,我需要澄清一下,我特别是在问C# .NET 3.5编译器。

6个回答

17

out 关键字本可以由编译器隐式添加,但我的理解是 C# 团队决定要求函数调用者明确使用 out 关键字,以提高参数的特性可见性。


他们可能也决定这样做,是因为他们希望尽可能让人们在使用它时感到痛苦,以此来阻止其使用。 - Michael Meadows
这是最好的答案。谢谢 :) - GateKiller
2
因为Anders Hejlsberg这么说了。 - BCS

10

编译器知道,你可能不知道。这是一种让你知道在你调用的函数中参数可能会发生改变的方式。


6

重点不在于编译器知道什么,而在于确保开发人员意识到此调用可能会改变变量X的值。

这在很大程度上源自C ++,其中引用值不需要调用站点监视器。无法查看C ++调用并准确了解其功能。 C ++中通过引用和值传递的参数在语义上有巨大的差异。


2

是的,编译器可以找出问题,但这样你就知道它将修改您传递的变量。

C#语言有很多我称之为安全网的东西,明确地告诉程序员正在发生什么。 以下是一些例子:

  1. 在switch语句中没有case穿透。
  2. 您不能在if语句中分配一个值:if(x = 5)会抛出错误而不是评估为true。

从技术上讲,第二个是不正确的。技术上的定义是if语句中的内容必须解析为布尔值。x = 5返回一个整数,而不是布尔值,因此编译器会报错。但是,以下代码是有效的:bool foo = false, bar = false; if (foo = bar) { } - FryGuy

1

http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx

out关键字会导致参数通过引用传递。这与ref关键字类似,不同之处在于ref要求在传递之前初始化变量。使用out参数时,方法定义和调用方法都必须明确使用out关键字。

由于DateTime.TryParse不需要oDate被初始化,因此必须传递out关键字。


0

好的,我不是C#专家,如果我搞错了,请有经验的人纠正我。

有两种方法可以将参数传递给C#函数:按值传递和按引用传递。这里的重大区别在于,在函数内修改参数是否会修改用于调用它的变量。这不是我相信编译器自己决定的事情。

由于您希望oDate是从调用者传递并更改的变量,因此您希望它通过引用传递。

另一个问题是它是否应该初始化。C#喜欢捕获未初始化时使用的变量,因为那几乎总是一个错误。在这种情况下,您可能只需声明要传递的内容,并使用TryParse()为其赋予第一个值。这是一种完全合法的技术,因此编译器应该允许它。这是另一件我不相信编译器能正确处理的事情。(我假设编译器还检查out参数在TryParse()中使用之前是否已初始化。)

因此,“out”具有两个目的。它建立了参数是通过引用传递的,并且预计在函数内部进行初始化。这两者都无法由编译器确定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接