45

我发现很多时候我不需要TryParse方法的out参数,但问题是它是必然的。在这里,我将展示一个不需要它的示例。

我想检查一个字符串是否为整数,如果是整数则打印“一个整数”;否则,打印“不是整数”。所以这里是代码:

string value = Console.ReadLine(); //Get a value from the user.
int num; //Why should I have it?? No need at all !

if (int.TryParse(value, out num))
{
    Console.WriteLine("An integer");
}
else
{
    Console.WriteLine("Not an integer");
}

我只是想知道为什么 TryParse 总是返回一个 out 参数?为什么没有 out 参数就没有重载?

4

4 回答 4

43

更新答案:

在最新版本的 C# 中,您可以声明输出参数 inline,这允许您删除示例中不需要的代码行:

string value = Console.ReadLine(); //Get a value from the user.

if (int.TryParse(value, out int num))
{
    Console.WriteLine("An integer");
}
else
{
    Console.WriteLine("Not an integer");
}

您可以简单地忽略代码中的结果,不再有多余的行。你仍然有额外的参数,但是呢?

潜在的“为什么”仍然是相同的,并且不太可能改变。该方法需要返回两件事,一个bool指示成功,一个指示成功int时的结果值。(我想不出另一种方式来传达结果,你可以吗?)由于一个方法只能返回一个东西,而自定义结果类型对此似乎有点矫枉过正,所以决定返回bool并让结果为一个out参数。一旦做出决定,它就必须在语言的整个过程中保持不变。

“他们”当然可以添加一个不输出int值的重载。但为什么?为什么要花费精力设计、记录、测试,并且正如我们所看到的那样,永远支持一种没有任何目的的方法,只是为极少数开发人员节省了几次击键?再次,非常不可能。

对于此类功能,当然欢迎您提出更改。我想,如果提案被接受,那将是非常酷的。我怀疑这个会是,但如果你对它充满热情,那么一定要去做。


原答案:

简短的回答是,“因为这就是方法的定义方式。” 也许 C# 语言团队的某个人偶然发现了这个问题,并提供了为什么做出决定的理由,但这在这一点上并没有太大变化。C# 是一种静态编译的语言,方法签名需要匹配,所以它就是这样。

(想象一下,如果他们改变了这一点并破坏.TryParse()了所有现有的代码库。那将是......糟糕。)

不过,您也许可以在自己的代码中解决这个问题。像扩展方法这样简单的东西可以为您解决问题:

public static bool IsInt(this string s)
{
    int x = 0;
    return int.TryParse(s, out x);
}

然后在您的代码中,您只需要从字符串值调用该方法:

string value = Console.ReadLine();
if (value.IsInt())
    Console.WriteLine("An integer");
else
    Console.WriteLine("Not an integer");
于 2013-10-25T14:13:49.333 回答
7

它具有out参数,因为大多数时候人们使用它时,他们想要解析的 int(或 double、decimal、datetime 或其他)。

如果您不需要/不需要解析的值,并且您发现自己一直在这样做,您可以编写自己的“包装器” .TryParse(),只需要字符串。

在这个例子中(你可以让它更通用,我敢肯定)你可以做类似的事情

public static bool TryParseNoOutput(this string value)
{
  int noNeed = 0;
  return int.TryParse(value, out noNeed);
}

然后在你的代码中(在这种情况下)你会调用:

string value = Console.ReadLine();
if(value.TryParseNoOutput()) Console.WriteLine("An Integer");
else Console.WriteLine("Not an integer."):

编辑: 正如评论中所指出的,当我将“int.TryParseNoOutput”定义为字符串的扩展时,我尝试调用它。答案已更新以反映这一点。

于 2013-10-25T14:12:38.133 回答
6

TryParse是确定inta 表示的相对复杂的操作string。如果有一个只返回 a 的重载,bool那么许多(没有经验的)开发人员很可能会遵循这种低效的模式:

int myInt = -1;
if(int.TryParse("123"))
    myInt = int.Parse("123");
于 2013-10-25T14:12:17.453 回答
2

为什么 TryParse 有一个 out 参数?
由于 TryParse 的实现方式非常简单。
您确定某事是否可解析的方法是解析它!如果你能够解析某些东西,那么它就是可解析的。如果你不能解析它,那么它是不可解析的。

因此,通过判断某个东西是否可解析,如果它可解析的,那么我们已经解析了它!丢弃这个解析值是愚蠢的(任何想知道某些东西是否可解析的人都可能对解析结果感兴趣),因此返回解析值。

它有一个 out 参数,因为解析的值是真正返回的 TryParse 调用的副产品。

于 2013-10-25T14:26:45.930 回答