我知道它不会抛出异常,因为它可能会快得多,而且,你最有可能使用它将输入转换为你可以使用的数据,所以我不认为它是这样使用的经常在绩效方面做出很大的改变。
无论如何,我看到的示例都是带有TryParse
的if / else块的行,else返回错误消息。对我来说,这与使用try / catch块和catch返回错误消息基本相同。
那么,我错过了什么吗?是否存在实际有用的情况?
答案 0 :(得分:23)
除了您自己提到的性能方面,还存在语义差异:
使用try / catch是出于特殊情况。输入无效数据是您所期望的,而不是特殊的。
答案 1 :(得分:12)
它非常简单:如果您在遇到无效数据时想要例外,请使用Parse
;如果不这样做,请使用TryParse
。因此,你的问题似乎是:
如果数据无效,为什么不想要例外?
异常仅应用于例外情况,而无效的数据可能不是例外情况。也许你正在编写一个数据清理程序,它希望获得无效数据,并试图在数据无效时推断出合理的值。也许数据并不那么重要,你可以跳过包含它的记录。
这取决于上下文,并且可以选择Parse
和TryParse
方法,为您选择适当的解析机制。
答案 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。这不是一个例外情况,因为像其他人一样,你应该为它做好计划。