在方法中使用'out'或'ref'参数的正当理由是什么?

时间:2011-10-15 19:43:13

标签: c#

我鄙视和参考方法的参数。恕我直言,他们使代码不那么干净,并提供副作用的机会。但我承认,我可能不理解他们的用处,这可能解释了我厌恶的一部分。请问有人可以为out或ref解释一个有效的案例吗?

4 个答案:

答案 0 :(得分:19)

基本上,如果您需要返回多个值,则可以使用Tuple<,>或自定义类型来封装值。规范示例可能是int.TryParse和相关方法。他们希望回传两条信息:

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

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

我不会说我鄙视 outref参数,但我相信它们只能偶尔使用,并且只有在没有更好的情况下才会使用替代。我在Stack Overflow上看到的ref的大部分用法都是由于对参数传递的误解造成的。

答案 1 :(得分:7)

out提供了一种返回多个值的方法。 ref是相同的,除了您传入值。

请注意,即使声明没有ref,也可以改变对象(假设它在第一个位置是可变的)。

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

答案 2 :(得分:6)

“新”(C#4.0)lock使用ref(从技术上讲,lock语句是新Monitor.Enter重载的语法糖。如果没有: - )

,就不可能做到这一点
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值的原因是,return true Monitor.Enterbool acquiredLock = ref之间可能会发生异常,让您的程序留下问题“锁定了吗?“使用{{1}}参数可以解决此问题。

答案 3 :(得分:2)

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

int x;
Foo(out x); 

int y;
Foo(ref y); 

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