使用'out'的正当理由是什么?或& # 39;裁判# 39;参数
本文关键字:参数 裁判 正当理由 out 使用 是什么 | 更新日期: 2023-09-27 18:11:26
我鄙视out和ref作为方法的参数。恕我直言,它们使代码不那么干净,并为副作用提供了机会。但我承认,我可能不明白它们的用处,这可能是我厌恶它们的部分原因。拜托,谁能解释一下判出局或判犯规的有效理由?
基本上,如果您需要返回多个值,那么使用Tuple<,>
或自定义类型来封装值是另一种选择。典型的例子可能是int.TryParse
及其相关方法。他们想要传达两条信息:
- 解析值
- 解析是否成功。
现在这些实际上在这种情况下已经使用返回类型int?
等来编写,但对于其他情况也是相同的原则。(例如,Dictionary<,>.TryGetValue
,其中存储在字典中的值可能合法为null。)
out
和ref
参数,但我确实认为它们只应该偶尔使用,并且只有在没有更好的替代方案时才应该使用。我在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.Enter
的return true
和bool acquiredLock =
之间可能会发生异常,从而使程序产生这样的问题:"锁被锁了吗?"使用ref
参数可以解决这个问题。
它们几乎是相同的-唯一的区别是作为out
参数传递的变量不需要初始化,并且使用out
参数的方法必须将其设置为某些东西。
int x;
Foo(out x);
int y;
Foo(ref y);
Ref
参数用于可能被修改的数据,out
参数用于已经使用返回值的函数(例如int.TryParse
)的额外输出的数据。