【问题标题】:How to distinguish different plain exceptions?如何区分不同的普通异常?
【发布时间】:2011-02-20 13:16:08
【问题描述】:

如果我不想创建自定义异常,那么捕获时如何区分它们?

if (somethingIsWrong)
   throw new Exception("Something is wrong.");
else if (anotherthingIsWrong)
   throw new Exception("Anotherthing is wrong.");
else
   throw Exception("Nothing is wrong!");

// Now when catching them:

catch (Exception ex)
{
   if (ex.Message.Contains("Something"))
      ShowUserErrorThatSomethinIsWrong();
   else if (ex.Message.Contains("Another"))
      ShowUserErrorThatAnotherthinIsWrong();
   // ...
}

我希望 System.Exception 有一个 ErrorNumber 属性来自定义异常:

if (somethingIsWrong)
   throw new Exception(1001, "Something is wrong.");

// And catching them this way:

if (ex.ErrorNumber = 1001)
   // ...

我知道可以从System.Exception 扩展MyExceptionClass,但有没有更好的解决方案?

这与我的另一个问题有关,您可以找到 here

【问题讨论】:

  • 为什么不想创建自定义异常?
  • 知道为什么你不想创建显式异常类会很有趣——因为它们是 .NET 的方式,并且会为你提供高效和分层的错误捕获/过滤。 . 当然,错误编号有助于指向文档,但维护起来很麻烦。

标签: c# exception exception-handling try-catch


【解决方案1】:

创建自己的异常类型这里的解决方案。

可以HResult 设置为异常并以这种方式抛出它 - 但这是一件可怕的事情。

该语言旨在根据异常类型而不是错误代码来捕获异常。

当然,如果您有几个类似的异常以及一些可能对代码捕获感兴趣的额外信息,您可以将这些额外信息添加到自定义异常的属性中。

【讨论】:

    【解决方案2】:

    这正是我要引入自定义异常的情况。虽然您不应该仅仅因为可以就创建自定义异常,但如果您遇到没有合适的框架异常或名称会误导的情况,请创建自定义异常!

    您提出的代码会使区分异常更难,调用者必须对您的代码做出假设。对于自定义例外,情况并非如此。

    【讨论】:

      【解决方案3】:

      通过扩展 System.Exception 创建自定义异常是可行的方法。你为什么不想这样做?

      优点:

      • 您可以按类类型捕获所有自定义异常(而不是使用丑陋的 .contains)
      • 您可以在捕获后添加要处理错误的 ErrorNumber 属性
      • 这是最干净、直接、优雅的解决方案。

      有什么理由不使用这种方法吗?

      【讨论】:

        【解决方案4】:

        我会说最好不要抛出 Exception 对象,因为它们太笼统了。框架内有许多从Exception 派生的类,通常情况下有一个适合您所处的场景。如果不是,则使用您自己的自定义类扩展Exception

        例如,如果您正在验证方法中的参数,并发现一个不应该为 null 的参数,则抛出 ArgumentNullException。如果有两件事试图无序完成,请抛出InvalidOperationException。您可以单独捕获这些异常:

        try
        {
        }
        catch (ArgumentNullException argException)
        {
        }
        catch (InvalidOperationException opException)
        {
        }
        

        您可能会发现这种方法过于笼统,但我想说的是,高级组件(例如 UI)并不需要知道出错的确切细节,只需知道“某事”出错了。例如,如果数据库命令出现问题,您可能会收到 SqlException 抛出。您可以捕获它,记录一些详细信息,然后抛出更一般的异常。

        【讨论】:

          【解决方案5】:

          好吧,您“应该”在 .NET 中创建自己的异常。异常模型以这种方式效果最好。

          如果你真的想要一个错误代码,你可以创建自己的异常并只使用它。

          public class ErrorCodeException : Exception
          {
              private readonly int _errorCode;
              public ErrorCodeException(int errorCode)
              {
                  _errorCode = errorCode;
              }
          
              public ErrorCodeException(int errorCode, string message)
                  : base(message)
              {
                  _errorCode = errorCode;
              }
          
              public int ErrorCode { get { return _errorCode; } }
          }
          

          编辑
          如果您出于调试目的想要准确找出抛出的所有异常中的哪一个,最好查看堆栈跟踪,而不是为您可能抛出的每个异常分配一个序列号。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-20
            • 2014-09-20
            相关资源
            最近更新 更多