前几天有人问我他们什么时候应该使用参数关键字out而不是ref。虽然我(我认为)理解ref和out关键字之间的区别(之前已经问过了),最好的解释似乎是ref == in和out,有什么(假设或代码)的例子,我应该总是使用out而不是ref。

既然ref更通用,为什么还要用out呢?它只是语法上的糖吗?


当前回答

在c#中如何使用in或out或ref ?

All keywords in C# have the same functionality but with some boundaries. in arguments cannot be modified by the called method. ref arguments may be modified. ref must be initialized before being used by caller it can be read and updated in the method. out arguments must be modified by the caller. out arguments must be initialized in the method Variables passed as in arguments must be initialized before being passed in a method call. However, the called method may not assign a value or modify the argument.

以下类型的方法不能使用in、ref和out关键字:

Async方法,通过使用Async修饰符来定义。 迭代器方法,其中包括yield return或yield break语句。

其他回答

需要注意的是,in在c# ver 7.2是一个有效的关键字:

The in parameter modifier is available in C# 7.2 and later. Previous versions generate compiler error CS8107 ("Feature 'readonly references' is not available in C# 7.0. Please use language version 7.2 or greater.") To configure the compiler language version, see Select the C# language version. ... The in keyword causes arguments to be passed by reference. It makes the formal parameter an alias for the argument, which must be a variable. In other words, any operation on the parameter is made on the argument. It is like the ref or out keywords, except that in arguments cannot be modified by the called method. Whereas ref arguments may be modified, out arguments must be modified by the called method, and those modifications are observable in the calling context.

作为ref传递的参数必须在传递给方法之前初始化,而out形参在传递给方法之前不需要初始化。

使用out表示该参数未被使用,仅被设置。这有助于调用者理解您总是在初始化参数。

此外,ref和out不仅适用于值类型。它们还允许您重置引用类型从方法中引用的对象。

读音: Out =只初始化/填充一个参数(参数必须为空),将其plain返回 Ref = reference,标准参数(可能带有value),但函数可以修改它。

你应该使用out,除非你需要参考。

当数据需要被编组到另一个进程时,它会产生很大的不同,这可能会花费很高。因此,您希望避免在方法不使用初始值时编组初始值。

除此之外,它还向声明或调用的读者显示初始值是相关的(并可能被保留),还是被丢弃。

作为一个微小的区别,out形参不需要初始化。

out的示例:

string a, b;
person.GetBothNames(out a, out b);

其中GetBothNames是一个原子检索两个值的方法,无论a和b是什么,该方法都不会改变行为。如果调用到夏威夷的服务器,将初始值从这里复制到夏威夷是浪费带宽。使用ref的类似代码段:

string a = String.Empty, b = String.Empty;
person.GetBothNames(ref a, ref b);

可能会让读者感到困惑,因为看起来a和b的初始值是相关的(尽管方法名表明它们不是)。

引用的例子:

string name = textbox.Text;
bool didModify = validator.SuggestValidName(ref name);

这里的初始值与方法相关。