何时使用ref vs out

有人问我有一天当他们应该使用参数关键字out ,而不是ref 。 虽然我(我认为)理解refout关键字之间的区别(以前已经提到过),并且最好的解释似乎是ref == inout ,但是我应该始终如此的一些(假设或代码)示例out而不是ref

由于ref较为一般,为什么你想用out ? 它只是语法糖吗?


您应该使用out ,除非你需要ref

当需要将数据整理到例如另一个过程时,这会产生很大的差异,这可能是昂贵的。 所以当这个方法不使用它的时候,你想避免编组初始值。

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

作为次要区别,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的初始值是相关的(尽管方法名称表明它们不是)。

ref示例:

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

这里初始值与方法有关。


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

另外,ref和out不仅仅是值类型。 它们还允许您重置引用类型在方法内引用的对象。


从语义上讲, ref是同时提供“in”和“out”功能的,而out只提供“out”功能。 有一些事情需要考虑:

  • out要求接受参数的方法必须在返回之前的某个时刻为变量赋值。 您可以在一些键/值数据存储类(如Dictionary<K,V> )中找到此模式,其中您具有TryGetValue等功能。 这个函数接受一个out参数,该参数保存检索到的值。 调用者传递一个值到这个函数是没有意义的,所以out被用来保证在调用之后某个值会在变量中,即使它不是“真实的”数据(在TryGetValue键不存在)。
  • 在处理互操作代码时, outref参数的编组方式不同
  • 此外,请注意,尽管引用类型和值类型的值的性质不同,但应用程序中的每个变量都指向包含值的内存位置 ,即使对于引用类型也是如此。 恰恰相反,对于引用类型,包含在该内存位置中的值是另一个内存位置。 当您将值传递给一个函数(或进行任何其他变量赋值)时,该变量的值将被复制到另一个变量中。 对于值类型,这意味着类型的整个内容被复制。 对于参考类型,这意味着内存位置被复制。 无论哪种方式,它都会创建变量中包含的数据的副本。 唯一真正的相关性是处理分配语义; 当分配变量或按值传递(默认值)时,当对原始变量(或新变量)进行新分配时,它不会影响其他变量。 对于引用类型,是的,对实例所做的更改在双方都可用,但这是因为实际变量只是指向另一个内存位置的指针; 变量的内容 - 内存位置 - 实际上没有改变。

    使用ref关键字传递时,原始变量和函数参数都将实际指向相同的内存位置。 这又一次只影响分配语义。 如果一个新值被分配给一个变量,那么因为另一个指向同一个内存位置,新值将反映在另一侧。

    链接地址: http://www.djcxy.com/p/21357.html

    上一篇: When to use ref vs out

    下一篇: typedef struct vs struct definitions