为什么C#既有out又有ref?


18

C#具有outref关键字。为什么需要这两个?免责声明:我对C#并不了解。


3
Stack Overflow上没有跨站​​点副本吗?
彼得·莫滕森


2
您是否要求ref和之间的区别out?还是您在问,与按值参数(无修饰符)相比,按引用参数ref/ 的用法是什么out?或两者?
Jeppe Stig Nielsen

1
我觉得这个问题是类似的,但并不完全是DUP -至少如果从语言设计的角度考虑
jmoreno

Answers:


32

在实现方面,它们本质上是相同的东西,但是out传达的东西ref不一样:您不在乎输入。 这对您和工具来说意味着某些事情。例如,您可以将未初始化的变量传递给out参数,这不成问题,否则会出现问题,并且在函数中,您需要out在返回值之前为该参数分配一个值,而无需执行任何操作都有ref价值。


10
Ref vs out对编译器而言比对程序员而言更为重要。编译器必须确保在给变量赋值之前不读取变量,并out为其提供了一种方法,该方法可以更好地匹配您首先要如何处理变量。
Cort Ammon-恢复莫妮卡

您能否详细说明一下:'out'传达了'ref'不传达的信息。

4
@Neo:基本上我在回答中说的是:它表明您不关心将其用作输入,因此可以安全地将未初始化的值传递给out参数,因为接收该函数的函数不会从中读取。
梅森·惠勒

@MasonWheeler验证程序是否允许(和/或在接收端强制执行)?内部只是一个属性。
Random832

@ Random832:正如罗伯特在他的回答下发布的,请看一下Eric Lippert(前C#编译器专家)在stackoverflow.com/q/2876315上
梅森·惠勒

7

要理解这两个关键字,您需要了解通过引用传递值的含义。从本质上讲,这意味着,如果您修改在方法或函数中传递的参数变量,则在函数退出时该变量将保留其修改后的值。将参数声明为refout完成此操作,而普通参数变量将保留其原始值,即使您在函数中对其进行了修改。

ref和之间的唯一区别outout不需要在将变量传递给函数之前初始化变量,但是需要ref;while out 确实需要您为函数中的变量分配某些内容,但ref并非如此。


差异不存在差异吗?
monocell


2

你问。

C#拥有并引用了,为什么需要这两个。我没有C#的深入知识。为什么需要out和ref参数?

答案是它们不是必需的,例如,java也没有,而VB仅具有ref(并且在方法声明中仅需要ref)。

您可以轻松编写整个程序,而无需使用任何一个。

之所以存在它们,是因为它们偶尔有用。这就是为什么要有两个而不是一个的原因-因为区分“这是某物,如果需要可以对其进行修改”和“将该事物赋予新值”之间的区别是很有用的。

其他语言具有不同的优先级,因此可能包括也可能不包括这些或等效语言。他们甚至可能在两者中是否有用上存在分歧,因此可能会主动决定不实施其中之一。


1

其核心都refout提供一个机制,一个变量的地址传递给方法,以便它可以被更新-分配给refout参数更新调用者的上下文变量。它们的不同之处在于保证:out保证变量将被更新,ref而不是被更新。

从通话的另一端也有类似的区别。out我们方法的参数不能保证在到达时会包含任何有用的参数,并且必须在某个时刻将其设置为值,而ref可以假定参数具有值,并且我们不需要对其进行任何特定的设置。

这种差异会对代码分析,生成和优化产生影响,尽管这些代码在大多数时候对我们而言并不十分明显,但可能会对程序的最终运行方式产生一些影响。代码生成器可以将变量的分配推迟到调用之前,优化器可能会决定根据合同等可以更有效地对某些操作进行重新排序,等等。

在用法方面:作为一般规则,我使用out以下情况:当变量作为参数到达时以及ref在执行变量时,我都不关心变量的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.