简体   繁体   English

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

[英]Why do I have to specify the “out” keyword in C#?

Before I ask my question, please take a look at this example function:在我问我的问题之前,请看一下这个例子 function:

DateTime.TryParse("01/01/2000", out oDate)

Why do I need to specify the out keyword?为什么我需要指定out关键字? Shouldn't the compiler know this from the function's definition?编译器不应该从函数的定义中知道这一点吗?

I'm asking this out of pure curiosity in the hope that I will learn something new about the compiler.我纯粹出于好奇而问这个问题,希望我能学到一些关于编译器的新东西。

I should also clarify that I'm asking about the C# .NET 3.5 compiler in particular.我还应该澄清一下,我特别询问的是 C# .NET 3.5 编译器。

The out keyword could be implied by the compiler but my understanding is that the C# team decided to make the out keyword explicitly required by the caller of the function to increase visibility as to the nature of the parameter.编译器可能暗示 out 关键字,但我的理解是 C# 团队决定让 function 的调用者明确要求out关键字,以增加对参数性质的可见性。

The compiler does know, you may not.编译器知道,你可能不知道。 It's a way of letting you know that the parameter you are passing can change in this function you are passing it to.这是一种让您知道您传递的参数可以在您传递给它的 function 中更改的方式。

It's not about what the compiler knows, it's all about making sure the developer realizes this call can and will change the value of variable X.这不是关于编译器知道什么,而是确保开发人员意识到这个调用可以并且将会改变变量 X 的值。

A lot of this has it's roots in C++ where a reference value needs no call site monitor.其中很多都源于 C++,其中参考值不需要呼叫站点监视器。 It's impossible to look at a C++ call and know exactly what it will do.查看 C++ 调用并确切知道它会做什么是不可能的。 Parameters passed by reference and value in C++ have huge differences in semantics. C++中通过引用和值传递的参数在语义上有很大的不同。

Yeah the compiler could figure it out, but this way you know that it is going to modify the variable you are passing in.是的,编译器可以弄清楚,但是这样你就知道它会修改你传入的变量。

the C# language has a lot of what I would call safety nets that explicitely tell the programmer what is going on. C# 语言有很多我称之为安全网的东西,它们明确地告诉程序员发生了什么。 A couple of examples are:几个例子是:

  1. No fall through in switch statements.在 switch 语句中不会失败。
  2. You can't assign a value in an if statement: if(x = 5) throws an error instead of evaluating to true.您不能在 if 语句中赋值:if(x = 5) 会抛出错误而不是评估为真。

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

"The out keyword causes arguments to be passed by reference. This is similar to the ref keyword, except that ref requires that the variable be initialized before being passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword." "out 关键字导致 arguments 通过引用传递。这与 ref 关键字类似,只是 ref 要求在传递之前初始化变量。要使用 out 参数,方法定义和调用方法都必须显式使用out 关键字。”

Since the DateTime.TryParse does not require oDate to be initialized, you must pass the out keyword.由于 DateTime.TryParse 不需要初始化 oDate,因此您必须传递 out 关键字。

OK, I'm not a C# expert, so if I mess up will somebody please correct me?好的,我不是 C# 专家,所以如果我搞砸了,有人请纠正我吗?

There's two ways to pass a parameter to a C# function: by value and by reference.将参数传递给 C# function 有两种方法:通过值和通过引用。 The big difference here is whether modifying the parameter inside the function modifies the variable used to call it.这里最大的区别是修改function里面的参数是否修改了用来调用它的变量。 This is not something I'd trust the compiler to decide for itself.这不是我相信编译器自己决定的事情。

Since you want oDate to be a variable passed in from the caller, and changed, you want it passed by reference.由于您希望 oDate 是从调用者传入的变量,并且已更改,因此您希望它通过引用传递。

The other question is whether it should be initialized or not.另一个问题是它是否应该被初始化。 C# likes to catch when variables are used while uninitialized, since that's almost always an error. C# 喜欢在未初始化的情况下使用变量,因为这几乎总是一个错误。 In this case, you might well just declare what you're passing in, and use TryParse() to give it its first value.在这种情况下,您可能只需声明您传入的内容,并使用 TryParse() 为其赋予第一个值。 This is a perfectly legitimate technique, so the compiler should allow it.这是一个完全合法的技术,所以编译器应该允许它。 This is another thing I wouldn't trust the compiler to get right.这是另一件事我不相信编译器会正确。 (I assume the compiler also checks to make sure an out parameter is initialized before use in TryParse().) (我假设编译器还会检查以确保在 TryParse() 中使用之前初始化 out 参数。)

So, "out" serves two purposes.所以,“出”有两个目的。 It establishes that the parameter is passed in by reference, and that it is expected to be initialized inside the function.它确定参数是通过引用传入的,并且预计将在 function 内部进行初始化。 Neither of these can be determined by the compiler.这些都不能由编译器确定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM