使用'out'的正当理由是什么?或& # 39;裁判# 39;参数

本文关键字:参数 裁判 正当理由 out 使用 是什么 | 更新日期: 2023-09-27 18:11:26

我鄙视out和ref作为方法的参数。恕我直言,它们使代码不那么干净,并为副作用提供了机会。但我承认,我可能不明白它们的用处,这可能是我厌恶它们的部分原因。拜托,谁能解释一下判出局或判犯规的有效理由?

使用'out'的正当理由是什么?或& # 39;裁判# 39;参数

基本上,如果您需要返回多个值,那么使用Tuple<,>或自定义类型来封装值是另一种选择。典型的例子可能是int.TryParse及其相关方法。他们想要传达两条信息:

  • 解析值
  • 解析是否成功。

现在这些实际上在这种情况下已经使用返回类型int?等来编写,但对于其他情况也是相同的原则。(例如,Dictionary<,>.TryGetValue,其中存储在字典中的值可能合法为null。)

我不会说我鄙视 outref参数,但我确实认为它们只应该偶尔使用,并且只有在没有更好的替代方案时才应该使用。我在Stack Overflow上看到的ref的大多数使用都是由于对参数传递的误解。

out提供了返回多个值的方法。ref是相同的,除了也可以传递值。

请注意,即使没有使用ref声明对象,也可以改变对象(当然,首先假设它是可变的)。

我更喜欢out的替代方法是创建一个类来包含所有返回值并返回该类的单个实例。

"新的"(c# 4.0) lock使用ref(严格来说,lock语句是新Monitor的语法糖)。输入超载)。如果没有:-)

bool acquiredLock = false;
try
{
    Monitor.Enter(lockObject, ref acquiredLock);
    // Code that accesses resources that are protected by the lock.
}
finally
{
    if (acquiredLock)
    {
        Monitor.Exit(lockObject);
    }
}

所以在高度关键的地方有ref的空间。

简单地返回一个bool值是不够的,因为在Monitor.Enterreturn truebool acquiredLock =之间可能会发生异常,从而使程序产生这样的问题:"锁被锁了吗?"使用ref参数可以解决这个问题。

它们几乎是相同的-唯一的区别是作为out参数传递的变量不需要初始化,并且使用out参数的方法必须将其设置为某些东西。

int x;
Foo(out x); 
int y;
Foo(ref y); 

Ref参数用于可能被修改的数据,out参数用于已经使用返回值的函数(例如int.TryParse)的额外输出的数据。