如何在抛出自定义异常时显示错误消息

本文关键字:显示 错误 消息 自定义异常 | 更新日期: 2023-09-27 18:08:39

我现在刚刚开始讨论exceptionhandling这个话题。我读了很多关于它的积极的东西,所以我想我应该做同样的事情,因为我目前使用的错误代码技术真的很丑……

好的,我们有以下场景:一个用户在textbox中输入了他的密码。在按下登录按钮后,他会得到正面或负面的消息。

MainWindow.xaml

<TextBox x:Name="txtBoxUserPassword/>
<Button x:Name="btnLogin" Click="btnLogin_Click">Login</Button>

MainWindow.xaml.cs

private void btnCT_Click(object sender, RoutedEventArgs e)
{
     DataBase db = new DataBase();
     db.IsPasswordCorrect(this.txtBoxUserPassword.Text);
     // How can I catch here the exception from the class to 
     // show the error notification?
}

DataBase.cs

public class DataBase{
     public void IsPasswordCorrect(string password)
     {
          try{
              if(password != "fooBar")
              {
                  throw new InvalidPasswordException("You entered the wrong password. Try it again.");
              }
              else
              {
                  /*
                     ...
                  */
              }
          }
          catch(InvalidPasswordException ex){
              // What should I do here? I want to give the user an 
              // error message with the content "You entered the wrong   
              // password. Try it again."
          }
     }
}

InvalidPasswordException.cs

public class InvalidPasswordException: Exception
{
    public InvalidPasswordException(string message, Exception inner)
        : base(message, inner)
    {
    }
}

可以看到,这是我第一次使用exceptions。希望你能帮我一点忙。谢谢!

编辑

我把switch/case construct放在我的public void btnCT_Click()里面。

switch (CheckString("EnteredString"))
{
    case 1:
        MessageBox.Show("Error 1");
        break;
    case 2:
        MessageBox.Show("Error 2");
        break;
    case 3:
        MessageBox.Show("Error 3");
        break;
    case 0:
        MessageBox.Show("Successful");
        break;
    }

这是我从另一个类的方法。类名不重要。

public int CheckString(string enteredString)
{
    if(enteredString length is larger 25 chars)
        return 1;
    else if(enteredString contains special characters)
        return 2;
    else if(enteredString dosent contain any number)
        return 3; 
    else
        return 0;
}

如何在抛出自定义异常时显示错误消息

我必须说的第一件事是,您不需要仅为此定制异常。只看方法的名称(IsPasswordCorrect),任何人都希望这个方法返回一个真/假布尔值,而不是一个异常。

你可以有一个更简单的

public class DataBase
{
     public bool IsPasswordCorrect(string password)
     {
          if(password != "fooBar")
             return false;
          else
             return true;
     }
}
.... at the UI level ....
if(!db.IsPasswordCorrect("notA_fooBar"))
   MessageBox.Show("You entered the wrong password. Try again");
else
   ....

然而,如果你真的需要抛出一个异常(请记住,这是一个代价高昂的操作,在性能方面),那么不要在抛出它的同一个方法中捕获它,而是让它膨胀到调用代码

 public bool IsPasswordCorrect(string password)
 {
      if(password != "fooBar")
         throw new InvalidPasswordException("You entered the wrong password. Try again");
      ....
 }

和在调用代码中(在UI级别)添加try catch块

private void btnCT_Click(object sender, RoutedEventArgs e)
{
     try
     {
          DataBase db = new DataBase();
          db.IsPasswordCorrect(this.txtBoxUserPassword.Text);
          // If you reach this point the password is correct
          // But it is ugly and unclear to any reader....
     }
     catch(InvalidPasswordException ex)
     {
         MessageBox.Show(ex.Message);
     }

在任何情况下,异常只能用于异常的原因。你不用它们驱动你的代码。在这种情况下,最好的方法是返回一个true/false值。


当失败原因很复杂时,我通常使用这种方法

bool ok = true;
ok = database.IsPasswordCorrect("fooBar");
if(ok) ok = database.Method1();
if(ok) ok = database.Method2();
if(ok) ok = database.Method3();
if(!ok)
   MessageBox.Show(database.LastErrorMessage);
public class Database
{
    public string LastErrorMessage { get; set; } 
    public bool Method1()
    {
        if(errorFoundForReason1)  
        {
             LastErrorMessage = "Error found for reason1";
             return false;
        }
        if(errorFoundForReason2)  
        {
             LastErrorMessage = "Error found for reason2";
             return false;
        }
        ....
        return true;
    }
}

当然,数据库类中的每个布尔方法,当有失败的原因时,在返回false之前,设置一个全局变量,其中包含失败所涉及的确切错误消息,以便客户端代码在完成调用后可以轻松处理该消息。