C# 捕获异常

5

在try/catch语句中,我应该使用哪种异常来发现用户输入的数据格式错误?

示例:

try
{
    string s = textBox1.Text;
    // User inputs an int
    // Input error
    MessageBox.Show(s);
}
catch(what exception)
{
    MessageBox.Show("Input in wrong format");
}

谢谢


我没有看到你发布的代码有任何异常情况。假设没有灾难性故障或其他类似问题,这段代码将始终按预期工作。如果无法验证输入,请不要使用异常处理。您可以使用异常来捕获所有异常类型。 - Jonathan Wood
这段代码不应该失败,所以它是一个糟糕的例子,但一些常见的类型转换异常包括InvalidCastException、FormatException、ArgumentNullException和OverflowException,当然还有其他依赖于转换操作的异常。 - Manatherin
4个回答

25

不要这样做。这是滥用异常处理的行为。你试图做的被称为 异常驱动编程,这是一种反模式

异常就是它听起来的意思,即规范之外的情况。它由你没有考虑到的某些事物定义,或者仅仅是无法通过传统的验证来解释。在这种情况下,你肯定可以提前检查数据格式问题。例如:

if(!ValidateText(textBox1.text)) // Fake validation method, you'd create.
{
  // The input is wrong.
}
else
{
  // Normally process.
}

5
意料之外的输入很常见,绝对不算例外。 - Neil N
1
@Sogger:不是很对。用户无法捕获异常,那么当用户执行不正确的操作时抛出异常有什么意义呢? - siride
这取决于应用程序是什么。输入不一定来自坐在电脑前的用户,它可以来自外部数据库或其他来源。此外,除非您正在处理大量输入,否则if/else和try/catch之间的区别对程序的实际有用性只是语义上的区别。我相信,在非错误情况下,try{parse}甚至比tryparse;parse;更快,即使是高容量处理。我发现自己使用trycatch的时候是当存在多个输入验证时,那么代码比10个以上的ifelse块更易读/可维护。 - Sogger
1
@Sogger 你有点牵强附会了。总是有一些假设的理由不去做某件事情——而且这里很清楚地定义了 OP 正在尝试实现什么。 - George Johnston
相信一个应用程序会有多个输入或来自非用户来源的输入并不是一件难以理解的事情。我发表评论的唯一原因是因为你的回答使用了概括性的说法,我想指出对于后来的读者来说,如果他们使用try-catch并不是一个坏人或“反对派”。 - Sogger
Sogger,输入源无关紧要。无论平台/来源如何,将其解析为整数的细微差别都是相同的。 - Neil N

10

避免使用异常来控制程序流程。

如果您想让文本框变成一个整数,这就是int.TryParse()方法发挥作用的地方。

int userInt;
if(!TryParse(textBox1.Text, out userInt)
{
    MessageBox.Show("Input in wrong format");
}

2
您可以使用Exception ex来捕获所有异常。如果您想要捕获更具体的异常,那么您需要查看您正在使用的函数的文档以检查输入的有效性。例如,如果您使用int.TryParse(),那么您将需要捕获FormatException等其他异常(参见:http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx了解更多信息)。

嗯,我关注的是根据问题找出要使用哪个异常。但我认为George的答案最终更正确,因为OP绝对不应该在这里使用异常。 - siride

1

您可以像下面这样创建自己的异常:

public class FormatException : Exception

在你的源代码中,可能是这样的...
if (not int) throw new FormatException ("this is a int");

然后,在你的 catch 中...

catch(FormatException fex)

虽然从技术上讲是正确的,但这不是一个好的模式(请参见被接受的答案)。 - Justin

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