C# WinForm中的异常处理

C# WinForm中的异常处理,c#,winforms,exception-handling,C#,Winforms,Exception Handling,我是C#编程的初学者。我在使用表格申请建筑时遇到了小问题。我会尽力在我的能力和经验范围内恰当地解释它。当我试图处理由在Form1中实例化的Class1引起的异常时,问题得到了解决。假设我在Class1中有函数“publicintcalc(inta,intb)”。在Form1中,我实例化了这个类来调用它的“Calc”函数。如果我想发送错误消息(f.e:除以零),我必须将函数调用包装到try/catch元素中: //表格1: Class1 C1 = new Class1(); int a = 5;

我是C#编程的初学者。我在使用表格申请建筑时遇到了小问题。我会尽力在我的能力和经验范围内恰当地解释它。当我试图处理由在Form1中实例化的Class1引起的异常时,问题得到了解决。假设我在Class1中有函数“publicintcalc(inta,intb)”。在Form1中,我实例化了这个类来调用它的“Calc”函数。如果我想发送错误消息(f.e:除以零),我必须将函数调用包装到try/catch元素中:

//表格1:

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;
}
。。。问题是,如何将消息(dividebyzerotexception e)放入我的Form1中,以便能够处理它并发送消息。我不想在Form1中创建一些静态函数,只是为了从Class1访问其中的MessageBox类,因为它在正确的OOP功能和Class1的可重用性方面没有意义。我读过关于事件和委托(我理解它是指向类似于C++的函数的简单指针)的书,但不知何故它令人困惑,我未能将此技术应用到我的代码中。请你写一个简单的例子,给我指出正确的方向

谢谢你们


Cembo

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

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

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
}

为了让它进入调用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
}
不管你需要什么样的逻辑,让它简单明了


然后处理表单中的错误。我建议您在
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));
    }

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

-1这是通过返回值产生的错误代码。任何调用Calc的函数现在都必须显式处理错误(通过打印消息或类似内容),或者将其传递给调用方。现在,整个链必须传递错误消息。异常允许您在适当的位置处理错误,而不必在整个调用链中传递错误(容易出错且繁琐)。我喜欢这样,好的防御性编码,即使您说在这种情况下有点过度:)+1
    [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));
    }