为什么TryParse方法使用out参数而不是ref

本文关键字:ref 参数 out TryParse 方法 为什么 | 更新日期: 2023-09-27 18:26:01

在这个问题的后面,询问了out参数的行为,但更关注的是为什么这些TryParse方法使用out而不是ref

在某些情况下,您确实希望在解析之前初始化参数的值,并在解析失败时保留该值,但并不关心它是否失败。但是,由于out参数,该值被重置。

这种情况可能是这样的。。。

int arg = 123;
Int32.TryParse(someString, ref arg);

然而,由于out参数,我们必须这样写,这更详细。。。

int arg;
if(!Int32.TryParse(someString, out arg)
{
    arg = 123;
}

我意识到知道解析失败可能非常有用,但ref的使用并不排除这一点。

那么,为什么这些TryParse方法使用out而不是ref呢?

为什么TryParse方法使用out参数而不是ref

因为正常的使用模式与您所描述的完全相反。

人们应该能够编写

int arg;
if (!Int32.TryParse(someString, ref arg)) {
    Waaah;
}

如果TryParse取了一个ref参数,这将需要一个无用的初始化。

真正的问题是为什么没有int? int.TryParse(string)方法。

使用out表示参数未被使用,仅被设置。调用程序需要在方法返回之前分配一个值:

int n;
if (Int32.TryParse("47", out n)) { // Works fine; `n` will be set to the
  // ..                            // result of the parse.
}

如果使用ref,则必须事先初始化该值,这很愚蠢,因为它无论如何都会被覆盖:

int n;
if (Int32.TryParse("47", ref n)) { // Kablammo! `n` isn't initialized.
  // ..
}

这正是TryParse的要点:保证out参数中有一个值,表示解析尝试的输出。true或false的返回值表示您应该关心结果还是忽略它。

这是因为out参数更适合该方法。

如果它使用了ref参数,则必须为该方法提供输入。这不起作用:

int arg;
if (Int32.TryParse(someString, ref arg)) { // error - variable is not initialsed

该方法不期望在value参数中有任何输入,如果必须提供一个输入值,那么它将是什么,也不清楚如何使用。

根据我的经验,与想要提供默认值相比,您不想麻烦初始化的次数要多得多。Parse的设计就是考虑到了这一点。

这个问题很好,我不认为使用这样或那样的方法会有严重的问题。NET团队选择了out方法,因为如果不在int中添加一个单独的方法,他们就无法同时使用这两种方法,这将是令人厌恶的冗余。