【问题标题】:Error handling of user input in a List<int>List<int> 中用户输入的错误处理
【发布时间】:2013-08-08 22:45:43
【问题描述】:

我有以下代码:

       List<int> moneys = new List<int>();
       Console.WriteLine("Please enter the cost of your choice");
       int money = int.Parse(Console.ReadLine());
       moneys.Add(money);

如果您输入文本,则程序将停止工作并出现未处理的异常消息。我想知道如果有可能使程序不会停止工作,您将如何处理异常?

【问题讨论】:

  • 与其使用 Try/Catch 处理异常,不如使用 TryParse 代替 Parse,并检查返回值是否解析成功。

标签: c# list oop error-handling


【解决方案1】:
int money ;
bool pass = int.TryParse(Console.ReadLine(), out money);
if(pass)
       moneys.Add(money);

【讨论】:

  • 我会假设 TryParse 会在后台处理异常,因此没有真正需要在这里实现自己的 try...catch
  • @James 我不明白你。我向他展示了 2 个备选方案。 TryParseParse 给出完整答案。
  • TryParse 可能会在后台调用 Parse 或使用一些验证。我不知道,我真的不在乎。但两者都可能有用,具体取决于开发人员。
  • 我的意思是你的问题的第二部分是不必要的。这就像在说“这是做你需要的事情的推荐方式,这是另一种方式,它的工作时间要长 3 倍,而不是推荐”。第二部分是有效地使用异常来控制程序流,这并不是一个好主意。根据@Servy TryParse 甚至不会在后台抛出异常,因此更有理由使用它。
  • “长 3 倍且不推荐”是主观的。如果是例外情况,那么抛出异常可能会更好,如果速度不是问题。
【解决方案2】:

实现try-catch 块或使用Int32.TryParse

【讨论】:

    【解决方案3】:

    要在抛出异常后对其进行处理,请使用 try/catch 块。

    try
    {
    //input
    }
    catch(Exception ex)
    {
    //try again
    }
    

    您也可以使用 TryParse 预先处理它,并检查 int 是否为 null。

    【讨论】:

    • 处理Exception 并不是真正的好习惯,您最终可能会吞下其他与您尝试做的事情无关的异常。
    • 您也不应该对控制流使用异常。
    【解决方案4】:

    您应该使用TryParse 方法。如果输入无效,它不会抛出异常。这样做

    int money;
    if(int.TryParse(Console.ReadLine(), out money))
       moneys.Add(money);
    

    【讨论】:

    • +1 这对我来说是对该问题的最完整/简洁的答案。
    【解决方案5】:

    int.Parse 在解析字符串失败时抛出异常。您有 2 个选择:

    1) 使用 Try/Catch 处理异常

    try {
        int money = int.Parse(Console.ReadLine());
        moneys.Add(money);
    } catch {
        //Did not parse, do something
    }
    

    此选项允许更灵活地处理不同类型的错误。您可以扩展 catch 块来拆分输入字符串中的 3 个可能的错误,并使用另一个默认的 catch 块来处理其他错误:

    } catch (ArgumentNullException e) {
        //The Console.ReadLine() returned Null
    } catch (FormatException e) {
        //The input did not match a valid number format
    } catch (OverflowException e) {
        //The input exceded the maximum value of a Int
    } catch (Exception e) {
        //Other unexpected exception (Mostlikely unrelated to the parsing itself)
    }
    

    2) 使用 int.TryParse 返回 truefalse,具体取决于字符串是否被解析,并将结果发送到第二个参数中指定的变量中(使用 out关键字)

    int money;
    if(int.TryParse(Console.ReadLine(), out money))
        moneys.Add(money);
    else
        //Did not parse, do something
    

    【讨论】:

    • 假设代码块中抛出的唯一异常是输入格式是不明智的,最好更具体并捕获FormatException。话虽如此,我很确定TryParse 无论如何都会在幕后做到这一点,所以最好坚持下去。
    • 当它开始掩盖其他问题时会这样做。
    • 只要所有信息都在那里,它不会掩盖问题。它有助于理解。查看更新的答案。
    • @James TryParse 不会捕获异常,它会避免从一开始就抛出异常,这就是为什么它通常更可取的原因。
    • @Pluc 这很不寻常,因为我在这种情况下的绝大多数时间(这是相当常见的)没有必要区分因非数字字符而无效和因非数字字符而无效数字太大。一般来说,至少在大多数情况下,“无效”就足够了,除非特别说明,否则我不会假设其他情况。至于为什么不应该对控制流使用异常,两个主要原因是语义和性能。使用异常的代价是昂贵的,而且应该为真正的异常情况保留异常,因此得名。
    猜你喜欢
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    相关资源
    最近更新 更多