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

时间:2010-03-15 19:48:37

标签: c# exception exception-handling

我知道它不会抛出异常,因为它可能会快得多,而且,你最有可能使用它将输入转换为你可以使用的数据,所以我不认为它是这样使用的经常在绩效方面做出很大的改变。

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

那么,我错过了什么吗?是否存在实际有用的情况?

10 个答案:

答案 0 :(得分:23)

除了您自己提到的性能方面,还存在语义差异:

使用try / catch是出于特殊情况。输入无效数据是您所期望的,而不是特殊的。

答案 1 :(得分:12)

它非常简单:如果您在遇到无效数据时想要例外,请使用Parse;如果不这样做,请使用TryParse。因此,你的问题似乎是:

  

如果数据无效,为什么不想要例外?

异常仅应用于例外情况,而无效的数​​据可能不是例外情况。也许你正在编写一个数据清理程序,它希望获得无效数据,并试图在数据无效时推断出合理的值。也许数据并不那么重要,你可以跳过包含它的记录。

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

答案 2 :(得分:7)

尽可能使用TryParse - 使用它会比抛出异常便宜得多。

答案 3 :(得分: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方法更有意义。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

int int.TryParse返回一个bool,允许你测试它是否成功而不是捕获异常。我通常在信息被成功翻译的情况下使用它,我想使用它,但如果没有,它并不重要,我可以忽略失败,因为我想使用默认值,除非我得到一个有意义的在这种情况下,我将覆盖它,但如果该值没有意义,我将保留默认值。

该理论认为异常本质上是昂贵的,因此你不应该用它们来决定程序流程。您应该在语义错误的地方捕获它们,而不是可能被解释为数据流的东西。

答案 6 :(得分:0)

对于那些不介意在失败的解析(可能是无效的输入)上设置值为0或需要简洁的情况的情况,TryParse的返回码允许这样做。

答案 7 :(得分:0)

每次你有一个解析要执行,因为使用它比使用Exception更便宜,而且你可以使它成为一个简单的 if 语句的一部分而不是一个大的尝试... catch块

答案 8 :(得分:0)

我不是c#monkey但是......

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

TryParse将为您提供更多控制(例如,在文本框中突出显示错误),而不是依赖于异常机制。

答案 9 :(得分:0)

如果您正在对表单上的输入进行验证,则可以在返回false时在控件(或MessageBox或其他通知)上设置ErrorProvider。这不是一个例外情况,因为像其他人一样,你应该为它做好计划。