为什么.Net框架指南建议您不要使用ref / out参数?

显然,他们“令人困惑”。 那是认真的原因吗? 你能想到其他人吗?

您是否看到有多少开发人员不了解ref / out?

我在他们真正需要的地方使用它们,但不是这样。 它们通常只有在您想要有效地返回两个或更多值时才有用 – 在这种情况下,至少值得思考是否有一种方法可以使方法只做一件事。 有时使用ref / out 最合适的方法 – 各种TryParse方法等。

在我看来,它们被认为是代码气味,因为通常有一个更好的选择:返回一个对象。

如果您注意到,在.NET库中,它们仅用于某些特殊情况,即类似于tryparse的场景,其中:

  • 返回一个类意味着装箱值类型
  • 该方法的合同要求它快,因此装箱/拆箱不是一个可行的选择。

ref / out自动意味着可变性,而使用不可变值的函数式编程最近风靡一时。 尝试将对Dictionary.TryGetValue的调用插入LINQ查询。 API需要声明变量并破坏API中的任何“流畅性”。

这并不是说这是“原因”,而是一个“理由”的例子。

(也可以看看

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!181.entry

关于function语言如何处理这些API的评论。)

令人困惑可能是最好的理由。 令人困惑的意思是降低可维护性并增加引入细微错误的可能性。 我在与“goto”控制流程语句类似的视图中看到它们。 虽然它本身并不是坏事,但它导致许多人几十年来无法阅读/理解程序。

远离任何可能使您的代码更加混乱的事情。

话虽如此,这些关键字的存在可能是因为框架开发人员认为需要这样的东西。 如果没有合适的解决方法,请使用它们,但尽可能避免使用它们。

ref / out也不能与“Func”委托一起使用,因此这些样式API与使用委托的一些其他API相比不太可组合/可重用。

只是一个想法,当参数捕获目标方法中的执行状态而不是捕获返回的数据时,我发现ref / out是有用的。 当您想要从返回Customer对象的服务获取错误消息时,请考虑这种情况。

Customer GetCustomerById(int id, out string errorMessage); 

如果此方法失败,您可能会返回null Customer对象或抛出exception。 但是,如果我想知道错误的原因(validation?数据库?),我会使用参数。 这里的errorMessage参数与数据无关,只是用于捕获方法执行的错误。

就个人而言,如果我有一个预期返回两个或更多基本数据/值的方法,我会重新考虑我的代码的设计。

我被告知的原因是1.0 GC在使用ref / out时出现问题。 2.0中的GC(也可能不是1.1)没有这些问题所以我通常认为它是一个现在没有用的遗产。

@TraumaPony如果您向我们提供此.NET框架指南的源(URL或其他内容),那就没问题了。

您应该返回对象可能是他们建议不使用ref或out的最可能原因。

“ref”实际上只需要在传递标量值时使用,但我看到人们常常将它用于通过引用传递的对象。

代码复杂性的原因不够吗? 相比:

 int myValue; ReadFromSomewhere(ref myValue); 

至:

 int myValue = ReadFromSomewhere();