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

本文关键字:使用 ref 参数 out 框架 Net 为什么 | 更新日期: 2023-09-27 17:47:49

显然,它们"令人困惑"。这真的是原因吗?你能想到其他的吗?

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

你见过有多少开发人员不真正理解ref/out吗?

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

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

如果你注意到,在.NET库中,它们只在一些特殊情况下使用,即类锥虫场景,其中:

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

ref/out自动意味着可变性,而具有不可变值的函数式编程如今风靡一时。尝试在LINQ查询中插入对Dictionary.TryGetValue的调用。API要求声明变量,并破坏API中的任何"流畅性"。

这并不是说这是"原因",而是"原因"的一个例子。

(另请参见

http://lorgonblog.spaces.live.com/blog/cns!701679d17b6d310!181.输入

有关函数式语言如何处理此类API的评论。)

困惑可能是最好的原因。混乱意味着可维护性降低,引入细微错误的可能性增加。我从类似于"goto"控制流语句的角度来看待它们。虽然它本身并不坏,但几十年来,它已经导致了许多无法阅读/理解的程序。

远离任何会让你的代码变得更加混乱的东西。

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

ref/out也不适用于"Func"委托,因此这些风格的API与其他一些使用委托的API的可组合性/可重用性较差。

只是想一想,当参数捕获目标方法中的执行状态而不是捕获返回的数据时,我发现ref/out很有用。考虑一个场景,当您希望从返回Customer对象的服务中获得错误消息时。

Customer GetCustomerById(int id, out string errorMessage);

如果此方法失败,您可能会返回空的Customer对象或引发异常。然而,如果我想知道错误的原因(验证?数据库?),我会使用out参数。这里的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();