什么时候使用C#ref关键字一个好主意?

bwe*_*rks 29 .net c# parameters interface

我在生产代码中看到的参数越多,我遇到的误用就越多,它给我带来的痛苦就越多.我讨厌这个关键字,因为从框架构建的角度来看,它似乎很愚蠢.什么时候向代表用户传达可能会更改对象引用/值的概念?

相比之下,我喜欢关键词,在没有使用任何关键词的情况下我更喜欢,因为在使用它们时给予了保证.另一方面,Ref不能保证,除非你在被传入之前被迫初始化参数,即使它没有任何改变.

我不是一个圣人开发者; 我确信它有实际适用的用途.我只想知道它们是什么.

dtb*_*dtb 33

框架设计指南(一本书克齐斯茨托夫·克瓦林纳和布拉德·艾布拉姆斯)建议,以避免双方refout参数.

避免使用outref参数.

使用outref参数需要使用指针,理解值类型和引用类型的不同,以及处理具有多个返回值的方法.此外,outref参数之间的差异还没有被广泛理解.为普通受众设计的框架架构师不应期望用户掌握使用outref参数.

框架设计指南引用规范Swap方法作为有效的例外:

void Swap<T>(ref T obj1, ref T obj2)
{
    T temp = obj1;
    obj1 = obj2;
    obj2 = temp;
}
Run Code Online (Sandbox Code Playgroud)

但同时评论评论

交换总是出现在这些讨论中,但我没有编写实际上需要交换方法的代码,因为大学.除非你有一个很好的理由,避免outref干脆.

  • 我想在设计`TryParse`方法时,没有咨询Cwalina和Abrams.:) (21认同)
  • TryParse采用out参数,而不是ref - 这就是重点. (8认同)
  • @D Hoerster - 实际上这本书正面讨论了TryParse模式.这是一个"避免"指南,意味着有一些已知的情况,违反规则是有道理的. (4认同)
  • IDictionary <TKey,TValue> .TryGetValue方法也是如此.如果.NET框架不遵循他们的建议,这并不令人信服. (2认同)
  • 当然,对于我们这些*了解指针的人来说,ref在某些情况下是效率的宝贵补充 - TryParse&Swap就是很好的例子.规则应该是"考虑其他设计,而不是盲目地在任何地方使用ref,特别是如果你真的不明白ref意味着什么". (2认同)
  • 这是一个可怕的假设,即工程师之间普遍的沮丧. (2认同)

Tim*_*mwi 13

大多数Interlocked方法都使用ref参数(我相信你同意)这是一个很好的理由.


Mar*_*ell 10

我试图在公共API上避免它,但它绝对有用.可变值类型是一个重要的类型,特别是在CF之类的东西(由于平台要求,可变结构更常见).但是,也许我使用它的最常见的时间是将复杂算法的一部分重构为几个方法,其中状态对象是过度的,我需要传递多个值:

var x = .....
var y = .....
// some local code...
var z = DoSomethingSpecific(ref x, ref y); // needs and updates x/y
// more local code...
Run Code Online (Sandbox Code Playgroud)

等等.DoSomethingSpecific私有方法在哪里,只是搬出来保持方法责任可管理.