C# 如何区分不同的普通异常?

C# 如何区分不同的普通异常?,c#,exception,exception-handling,try-catch,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:

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

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,但有更好的解决方案吗


这与我可以找到的另一个问题有关。

好吧,您应该在.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; } }
}
编辑
如果出于调试目的,您希望准确地找出抛出的所有异常中的哪一个,那么最好查看堆栈跟踪,而不是为可能抛出的每个异常指定序列号。

好的,您应该在.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; } }
}
编辑
如果出于调试目的,您希望准确地找出抛出的所有异常中的哪一个,那么最好查看堆栈跟踪,而不是为可能抛出的每个异常指定序列号。

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

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

该语言设计用于根据异常类型而不是错误代码捕获异常


当然,如果您有几个类似的异常,其中包含一些额外的信息,这些信息可能是代码捕获它所需要的,那么您可以将这些额外的信息添加到自定义异常的属性中。

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

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

该语言设计用于根据异常类型而不是错误代码捕获异常


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

这正是我要介绍的自定义异常的情况。虽然您不应该仅仅因为可以创建自定义异常而创建自定义异常,但如果您遇到的情况中没有fitting framework异常,或者名称可能会误导您,请创建自定义异常


您提出的代码将使区分异常变得更加困难,调用方将不得不对您的代码进行假设。对于自定义异常,情况就不是这样了。

这正是我要介绍的自定义异常的情况。虽然您不应该仅仅因为可以创建自定义异常而创建自定义异常,但如果您遇到的情况中没有fitting framework异常,或者名称可能会误导您,请创建自定义异常


您提出的代码将使区分异常变得更加困难,调用方将不得不对您的代码进行假设。对于自定义异常,情况并非如此。

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

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

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

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

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

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

try
{
}
catch (ArgumentNullException argException)
{
}
catch (InvalidOperationException opException)
{
}
您可能会发现这种方法过于笼统,但我想说的是,一个高级组件(例如UI)并不需要知道出了什么问题的确切细节,只需要知道出了什么问题。例如,如果数据库命令出错,可能会引发SqlException。你可以用c
对此,记录一些详细信息,然后抛出一个更一般的异常。

通过扩展系统创建自定义异常。异常是解决方法。你为什么不想那样做

优点:

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

通过扩展System.Exception创建自定义异常是一种方法。你为什么不想那样做

优点:

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

为什么不想创建自定义异常?了解为什么不想创建显式异常类将非常有趣,因为它们是.NET中的一种方式,将为您提供高效的分层错误捕获/筛选。。。当然,错误号有助于指向文档,但是维护起来很麻烦。请看这里:为什么不创建自定义异常?了解为什么不创建显式异常类将非常有趣,因为它们是进入.NET的方式,将为您提供高效的分层错误捕获/过滤。。。当然,错误号有助于指向文档,但维护起来很麻烦。请参见此处: