【问题标题】:Is there a way to throw custom exception without Exception class有没有办法在没有异常类的情况下抛出自定义异常
【发布时间】:2015-07-11 17:30:58
【问题描述】:

在 C#(即 .NET 中)中是否有任何方法可以引发自定义异常,但无需编写所有代码来定义您自己的从 Exception 派生的异常类?

我正在考虑类似的东西,例如在 Oracle PL/SQL 中你可以简单地编写

raise_application_error(-20001, 'An arbitary error message');

在任何地方。

【问题讨论】:

  • 您可以将自定义属性添加到自定义异常类,所以您不能只创建一个自定义异常类,然后为异常的“类型”添加一个 Enum 吗?
  • 如果throw new Exception("An arbitary error message"); 对您不起作用,最好扩展一个问题来解释原因。
  • 不,没有也不应该有。
  • @ZoharPeled 你这么说的理由是什么?
  • @mason:我的理由很简单:异常携带的信息比简单的消息要多得多。它们携带堆栈跟踪,它们可以携带内部异常等。PL/SQL 不会引发错误。另一个原因是在不使用 Exception 对象的情况下引发错误消息会违反正常的异常模式,而 .Net 没有为此提供 try...catch 机制。 (

标签: c# asp.net exception


【解决方案1】:
throw new Exception("A custom message for an application specific exception");

不够好?

如果相关,您还可以抛出更具体的异常。例如,

throw new AuthenticationException("Message here");

throw new FileNotFoundException("I couldn't find your file!");

可以工作。

请注意,根据MSDN,您可能throw new ApplicationException()

不自定义 Exception 的主要缺点是调用者将更难以捕获 - 如果不对异常进行一些时髦的检查,他们将不知道这是一般异常还是特定于您的代码的异常。消息属性。你可以做这样简单的事情:

public class MyException : Exception
{
    MyException(int severity, string message) : base(message)
    {
        // do whatever you want with severity
    }
}

避免这种情况。

更新:Visual Studio 2015 现在提供一些异常扩展类的自动实现 - 如果您将光标放在 : Exception 上打开快速操作和重构菜单,只需告诉它“生成所有构造函数”即可。

【讨论】:

  • 你不应该使用ApplicationException类,看这里的备注:msdn.microsoft.com/en-us/library/…
  • ApplicationException 已被有效弃用。
  • 这不是 OP 要求的“自定义”异常。但是,我更感兴趣的是理解这句话:“请注意,您可能不应该抛出 new Exception(),因为这可能会导致其他问题。” - 你能进一步解释一下吗?
  • 抱歉,搞混了!现在换了。
  • @MetroSmurf 想一想,它是一个例外,没有关于发生的事情的任何信息。最重要的是,如果不处理所有异常(catch Exception 而不是 catch SpecificException),就无法处理。
【解决方案2】:

Exception 类不是 abstract,并且与 .NET 中定义的大多数异常一样,在其中一个构造函数重载中采用 string message - 因此您可以使用现有的异常类型,但使用自定义消息。

throw new Exception("Something has gone haywire!");
throw new ObjectDisposedException("He's Dead, Jim");
throw new InvalidCastException(
    $"Damnit Jim I'm a {a.GetType().Name}, not a {b.GetType().Name}!");

因为这使用了已知的异常类型,所以第三方也可以更轻松地扩展您的库,因为他们不需要在 catch 语句中查找 MyArbitraryException

【讨论】:

  • 我必须记住InvalidCastException
  • @David 这是正确的,但所有 Exceptions 都应该是 DwightSchruteException("..") LOL 类型
【解决方案3】:

简短回答 - 不。

强制继承自定义异常是有充分理由的;人们需要能够处理它们。如果您可以在没有类型的情况下抛出自定义异常,那么人们将无法捕获该异常类型。

如果您不想编写自定义异常,请使用现有的异常类型。

【讨论】:

    【解决方案4】:

    您可以只抛出 .NET 中可用的异常之一:

    throw new System.ArgumentException("Parameter cannot be null", "original");
    

    或更通用的:

    throw new ApplicationException("File storage capacity exceeded.");
    

    【讨论】:

      【解决方案5】:

      在 c# 中创建自定义异常的一种简单方法是使用泛型类。如果您需要创建大量异常(即,如果您需要在单元测试中区分它们),这将大大减少代码行数。

      首先创建一个名为CustomException<T>的简单类:

      public class CustomException<T> : Exception where T : Exception
      {
          public CustomException() { }
          public CustomException(string message) : base(message){ }
          public CustomException(string message, Exception innerException) : base(message, innerException){ }
          public CustomException(SerializationInfo info, StreamingContext context) : base(info, context){ }
      }
      

      您可以根据需要(或需要)覆盖任意数量的构造函数和方法。为了创建新的异常类型,只需添加新的单行类:

      public class MyCustomException : Exception { }
      public class SomeOtherException : Exception { }
      

      如果您想引发自定义异常,请使用:

      throw new CustomException<MyCustomException>("your error description");
      

      这使您的异常代码保持简单,并允许您区分这些异常:

      try
      {
          // ...
      }
      catch(CustomException<MyCustomException> ex)
      {
          // handle your custom exception ...
      }
      catch(CustomException<SomeOtherException> ex)
      {
          // handle your other exception ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-31
        • 1970-01-01
        • 1970-01-01
        • 2018-07-20
        • 2017-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多