如何区分不同的普通例外?

时间:2011-02-20 13:16:08

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

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

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.ExceptionErrorNumber属性,可以通过这种方式自定义异常:

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

// And catching them this way:

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

我知道可以从MyExceptionClass延长System.Exception,但还有更好的解决方案吗?

这与我可以找到here的其他问题有关。

5 个答案:

答案 0 :(得分:4)

在此创建自己的异常类型 解决方案。

可以在异常上设置HResult并以此方式抛出 - 但这是一件可怕的事情。

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

通过扩展System.Exception来创建自定义例外是最佳选择。你为什么不想这样做?

优点:

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

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

答案 3 :(得分:0)

好吧,你“应该”在.NET中创建自己的异常。异常模型最适合这种方式。

如果你真的想要一个ErrorCode,你可以创建自己的Exception并只使用它。

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; } }
}

修改
如果您出于调试目的想要确切地找出抛出的所有异常中的哪一个,那么查看堆栈跟踪而不是为每个可能抛出的异常分配序列号要好得多。

答案 4 :(得分:0)

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

例如,如果您正在验证进入方法的参数并且在不应该的时候找到一个为null,则抛出ArgumentNullException。如果有两件事情无法完成,请抛出InvalidOperationException。您可以单独捕获这些例外:

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

你甚至可能会发现这种方法过于笼统,但我会说高级组件(例如UI)并不真正需要知道出错的确切细节,只是“​​某些东西”出错了。例如,如果数据库命令出现问题,您可能会抛出SqlException。您可以捕获它,记录一些细节,然后抛出更一般的例外。