为什么所有TryParse重载都有out参数?

Mis*_*sky 36 c# tryparse

我发现很多次我不需要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");
}
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*vid 31

更新答案:

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

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");
}
Run Code Online (Sandbox Code Playgroud)

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

潜在的"为什么"仍然是相同的,不太可能改变.该方法需要返回两个东西,bool表示成功,int如果成功则指示结果值.(我想不出另一种传达结果的方法,可以吗?)因为一个方法只能返回一个东西,并且自定义结果类型似乎bool有点过分,所以决定返回并得到结果一个out参数.一旦做出决定,就必须保持语言的持续时间.

"他们"当然可以添加一个不会输出int值的重载.但为什么?为什么要花费精力进行设计,记录,测试,并且正如我们所见,我们已经看到永久支持一种无用的方法,但为极少数开发人员节省了一些按键?再一次,非常不可能.

对于此类功能,您当然欢迎提出更改.我想,接受提案会很酷.我怀疑这个会是什么,但如果你对它充满热情,那么无论如何都要有它.


原答案:

简短的回答是,"因为这就是方法的定义方式." 或许很可能C#语言团队的某个人可能会发现这个问题,并为决策的原因提供理由,但这一点并没有太大变化.C#是一种静态编译的语言,方法签名需要匹配,所以这就是它的方式.

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

但是,您可以在自己的代码中解决此问题.像扩展方法这样简单的东西可以帮到你:

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

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

string value = Console.ReadLine();
if (value.IsInt())
    Console.WriteLine("An integer");
else
    Console.WriteLine("Not an integer");
Run Code Online (Sandbox Code Playgroud)

  • 但是,即使他计划使用`int.Parse`,也会让开发人员总是试图使用它. (2认同)
  • @TimSchmelter:确实如此.虽然开发人员可以在代码中完成不正确和低效的事情,但是在OP的示例中,这不是问题,但在其他情况下里程可能会有所不同. (2认同)
  • @MishaZaslavsky 我意识到这是一个非常古老的问题,但是在 C# 7 中,他们添加了使用以下语法丢弃 out 变量的功能:int.TryParse(myStr, out _)。显然,仍然有一个 out 变量,但他们明确地用它来表示您不关心结果的解析。这使代码更加清晰,并且比“, out var num)”稍微短一些。 (2认同)

All*_*enG 7

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

如果你不想/需要解析的值,并且你发现自己一直在做这件事,那么你可以编写自己的"包装器" .TryParse(),只需要接受字符串.

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

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

然后在你的代码中(在这种情况下)你会打电话:

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

编辑: 正如在评论中指出的那样,当我将其定义为字符串的扩展名时,我尝试调用"int.TryParseNoOutput".答案已更新以反映这一点.


Tim*_*ter 5

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

int myInt = -1;
if(int.TryParse("123"))
    myInt = int.Parse("123");
Run Code Online (Sandbox Code Playgroud)