【问题标题】:Exception handling in WinFormWinForm 中的异常处理
【发布时间】:2011-07-31 17:37:21
【问题描述】:

我是 C# 编程的初学者。我在使用表单构建应用程序时遇到了小问题。我会在我的能力和经验范围内尽量解释清楚。当我尝试处理由 Form1 中实例化的 Class1 引起的异常时出现问题。假设我在 Class1 中有函数“public int Calc(int a, int b)”。在 Form1 中,我已经实例化了这个类来调用它的“Calc”函数。如果我想发送错误消息(例如:除以零),我必须将函数调用包装到 try/catch 元素中:

//Form1:

Class1 C1 = new Class1();
int a = 5;
int b = 0;
int c = 0;

try{
   c = C1.Calc(a,b)
}
catch(DivideByZeroException e)
{
   // some error handling code
}

...我认为这个示例不是正确的 OOP 技术,所以我不得不决定将 try/catch 元素直接放入 Class1:

//类1:

public int Calc(int a, int b)
{
    int c = 0;
    try{
      c = a/b;
    }
    catch(DivideByZeroException e)
    {
      // .........
    }
    return c;
}

...问题是,我怎样才能将消息 (DivideByZeroException e) 输入我的 Form1 以便能够处理它并发送消息。我不想在 Form1 中创建一些静态函数只是为了从 Class1 到达其中的 MessageBox 类,因为它在正确的 OOP 功能和 Class1 的可重用性方面没有意义。我已经阅读了有关事件和委托的内容(我理解这是指向类似于 C++ 的函数的简单指针),但它有点令人困惑,我未能将这种技术应用到我的代码中。请你写一个简单的例子来指引我正确的方向。

谢谢大家

Cembo

【问题讨论】:

    标签: c# winforms exception-handling


    【解决方案1】:

    正确的技术确实是第一个。如果你不能在你的函数中处理它,那么你就没有业务尝试。将异常处理放在可以处理异常并且程序可以继续(或正常退出)并以适当方式通知用户错误的地方。

    【讨论】:

      【解决方案2】:

      我建议您在 Program.cs 文件中的应用中实现以下代码

          [STAThread]
          static void Main()
          {
              Application.EnableVisualStyles();
              Application.SetCompatibleTextRenderingDefault(false);
              Application.Run(new Form1());
      
              // -----------------
              Application.ThreadException += Application_ThreadException;
              // -----------------
          }
      
          static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
          {
              // Handle your exception here...
              MessageBox.Show(string.Format("There is an error\n{0}", e.Exception.Message));
          }
      

      这将在整个应用程序中捕获您未处理的异常。

      【讨论】:

        【解决方案3】:

        为了让它冒泡到调用 UI 的范围内,您需要在捕获后抛出异常,或者更好的是,根本不要抛出它 - 因为除以零会导致 CLR 抛出必要时例外。您可以在此处进行简单检查,而 Calc API 调用可能仍会引发异常。

        例如,只需检查Calc 调用之前的数据:

        if (a > 0 && b > 0)
        {
            var result = Calc(a, b);
        }
        else 
        {
            //tell the user to input valid data
        }
        

        Calc 方法中,您可以进行类似的检查并抛出相关异常:

        public int Calc(int a, int b)
        {
            if (a <= 0) throw new ArgumentException("appropriate message here");
            if (b <= 0) throw new ArgumentException("appropriate message here");
            ...
        }
        

        这里的想法是防止除以零,但在您的情况下可能有点过分,因为前面的示例表明您基本上可以提供相同的行为,但是现在您需要捕获异常:

        try
        {
            var result = Calc(a, b);
        }
        catch //use appropriate exception catches
        {
             //tell the user to input valid data
        }
        

        【讨论】:

        • 我喜欢这个,良好的防御性编码,即使你说在这种情况下它有点过分:) +1
        【解决方案4】:
        public int Calc(int a, int b)
            {
                int c = a/b;
            }
        

        用你需要的任何逻辑让它简单明了。

        然后在表单中处理错误,您一开始是如何做到的。

        【讨论】:

          【解决方案5】:

          一种简单的方法是将您的方法更改为类似的方式

          public int Calc(int a, int b, out string error)
          {
              error = string.empty;
              int c = 0;
              try
              {
                c = a/b;
              }
              catch(DivideByZeroException e)
              {
                   error = e.ToString();
              }
              return c;
          }
          

          现在你可以在调用者中检查

          string error; 
          int res = Calc( 1, 2, out error);
          if(!string.isnullorempty(error)
          {
              //error has occured
              messagebox.show(error);
          }
          else
          {
              //no error
              // you can proceed noramlly
          }
          

          【讨论】:

          • -1 这是通过返回值的错误代码发生了可怕的错误。
          • 现在任何调用 Calc 的函数都必须明确地处理错误(通过打印出消息或类似的东西)或将其传递给调用者。现在整个链必须传递错误消息。异常允许您在适当的位置处理错误,而不必在整个调用链中传递它(容易出错且乏味)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-06-26
          • 1970-01-01
          • 1970-01-01
          • 2021-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多