C#: 我什么时候应该使用TryParse?

14

我知道它不会抛出异常,因此可能会更快,但是,您很可能使用它将输入转换为可用的数据,因此我认为在性能方面并没有太大的区别。

无论如何,我看到的示例都是使用TryParse的if / else块,else返回错误消息。 对我来说,这基本上与使用try / catch块并让catch返回错误消息相同。

那么,我有遗漏什么吗? 这种情况真正有用吗?


3
值得注意的是,大多数代码示例(尤其是在.NET文档中)旨在演示某个功能的工作原理,而不是最佳实践。您可以使用TryParse设置错误消息,但也许更符合实际情况的做法是在输入(可能来自用户)无效时分配默认值。 - ThatBlairGuy
10个回答

23
除了你自己提到的性能方面,还有一个语义上的区别:
使用try/catch是用来处理异常情况的。输入无效数据是你预期会发生的事情,而不是异常情况。

5
谢谢你提到例外情况和验证的重要性,这是我非常关注的问题之一! - Jason Down
我只想补充一点,很多人可能会在if/else中使用它,并且在try/catch中使用.Parse可能会让一些人感到困惑(请原谅双关语)。 - Nate

12
这很简单:如果您遇到无效数据时想要异常,请使用Parse;如果不想,就使用TryParse。因此,您的问题似乎是:

为什么在数据无效时不想要异常?

只有在特殊情况下才应使用异常,并且数据无效可能不是特殊情况。也许您正在编写一个数据清理程序,它期望得到无效数据,并将尝试推断出当数据无效时合理的值。也许这些数据并不是那么重要,您可以跳过包含它们的记录。

这取决于上下文,选择使用ParseTryParse方法可以让您选择适当的解析机制。


7

在可能情况下,使用 TryParse - 使用它比抛出异常要便宜得多。


如果您没有合理的方法来处理TryParse失败呢? - Greg Beech

2
假设您正在阅读日志文件:
public IEnumerable<LogEntry> GetAllValidEntries() {
    while (!logReader.Finished) {
        string nextLine = logReader.ReadLine();
        LogEntry nextEntry;

        if (TryParseLogEntry(nextLine, out nextEntry))
            yield return nextEntry;
    }
}

private bool TryParseLogEntry(string line, out LogEntry logEntry) {
    logEntry = null;

    if (string.IsNullOrEmpty(line))
        return false;

    string[] cells = line.Split(';');
    if (cells.Length < 3)
        return false;

    DateTime time;
    decimal price;
    int quantity;

    // We just want to read this line of text as a LogEntry
    // IF it is valid; otherwise, there's no reason to throw
    // an error in the user's face
    if (!DateTime.TryParse(cells[0], out time) ||
        !decimal.TryParse(cells[1], out price) ||
        !int.TryParse(cells[2], out quantity))
        return false;

    logEntry = new LogEntry(time, price, quantity);
    return true;
}

由于上面的代码的整个目的是从一个序列中提取有效项(该序列可能包含一些无效项),因此我认为在这种情况下,TryParse 方法比要求有效输入的 Parse 方法更有意义。


1
如果您需要在解析失败时设置默认值,TryParse与if结合使用是一种很好的方法。

1

好的,int.TryParse 返回一个布尔值,允许您测试是否成功,而不是捕获异常。我通常在这样的情况下使用它:如果信息被成功转换,我希望使用它,但如果没有,那么它并不重要,我可以忽略失败,只要我想使用默认值,除非我得到了有意义的值,在这种情况下,我将覆盖它。但如果该值没有意义,我将保持默认值。

理论上说,异常本质上很昂贵,因此您不应该使用它们来控制程序流程。您应该在语义上出现错误的地方捕获它们,而不是可能被解释为数据流的地方。


0

对于那些不介意在解析失败时(例如无效输入)将值设置为0的情况,或者需要简洁的情况,TryParse的返回代码可以实现这一点。


0

每次你需要执行解析时,使用 Parse 要比异常捕获成本更低,而且你可以将其作为简单 if 语句的一部分,而不是一个大的 try...catch 块。


0

我不是C#的专家,但是...

异常会通过转移处理到catch块来中断正常的代码流程。

使用TryParse可以更好地控制(例如,在文本框中突出显示错误),而不是依赖于异常机制。


0
如果您正在对表单上的输入进行验证,当其返回false时,您可以在控件上设置ErrorProvider(或MessageBox或其他通知)。这不是一个异常情况,因为正如其他人所说,您应该计划处理它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接