简体   繁体   English

有没有办法在没有Exception类的情况下抛出自定义异常

[英]Is there a way to throw custom exception without Exception class

Is there any way in C# (ie in .NET) to throw a custom exception but without writing all the code to define your own exception class derived from Exception ? 有没有办法在C#(即在.NET中)抛出自定义异常,但没有编写所有代码来定义自己的异常类派生自Exception

I am thinking something similar you have for example in Oracle PL/SQL where you can simply write 我正在考虑类似于Oracle PL / SQL中您可以编写的类似内容

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

at any place. 在任何地方。

throw new Exception("A custom message for an application specific exception");

Not good enough? 还不够好?

You could also throw a more specific exception if it's relevant. 如果相关,您还可以抛出更具体的异常。 For example, 例如,

throw new AuthenticationException("Message here");

or 要么

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

could work. 可以工作。

Note that you should probably not throw new ApplicationException() , per MSDN . 请注意,根据MSDN ,您可能应该throw new ApplicationException()

The major draw back of not customizing Exception is that it will be more difficult for callers to catch - they won't know if this was a general exception or one that's specific to your code without doing some funky inspection on the exception.Message property. 不定制Exception的主要缺点是调用者将更难以捕获 - 他们不会知道这是一般异常还是特定于您的代码而不对exception.Message属性进行一些时髦的检查。 You could do something as simple as this: 你可以做一些简单的事情:

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

to avoid that. 避免这种情况。

Update : Visual Studio 2015 now offers some automatic implementation of Exception extension classes - if you open the Quick Actions and Refactoring Menu with the cursor on the : Exception , just tell it to "Generate All Constructors". 更新 :Visual Studio 2015现在提供了一些Exception扩展类的自动实现 - 如果您使用光标打开快速操作和重构菜单 : Exception ,只需告诉它“生成所有构造函数”。

The Exception class is not an abstract , and like most of the exceptions defined in .NET, takes a string message in one of the constructor overloads - you can therefore use an existing exception type, but with a customized message. 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}!");

Because this uses exception types that are known, it makes it easier for thrid parties to extend your libraries as well, since they don't need to look for MyArbitraryException in catch statements. 因为它使用已知的异常类型,所以它使得thrid方更容易扩展库,因为它们不需要在catch语句中查找MyArbitraryException

Short answer - no. 简短的回答 - 没有。

There is a good reason for enforcing the inheritance of custom exceptions; 有一个很好的理由来强制继承自定义异常; people need to be able to handle them. 人们需要能够处理它们。 If you could throw your custom exception without having a type, people wouldn't be able to catch that exception type. 如果您可以在没有类型的情况下抛出自定义异常,则人们将无法捕获该异常类型。

If you don't want to write a custom exception, use an existing exception type. 如果您不想编写自定义异常,请使用现有的异常类型。

You can just throw one of the exceptions that is available in .NET: 您可以抛出.NET中可用的一个例外:

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

Or more generic: 或者更通用:

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

An easy way to create custom Exceptions in c# is using a generic class. 在c#中创建自定义异常的简单方法是使用泛型类。 This reduces the lines of code dramatically if you need to create much exceptions (ie if you need to distinguish between them in your unit tests). 如果您需要创建很多异常(例如,如果您需要在单元测试中区分它们),这会大大减少代码行。

First create a simple class called CustomException<T> : 首先创建一个名为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){ }
}

You can override as many constructors and methods as you want (or need) to. 您可以根据需要(或需要)覆盖任意数量的构造函数和方法。 In order to create new Exception types just add new one-liner classes: 为了创建新的Exception类型,只需添加新的单行类:

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

If you want to raise your custom exception use: 如果要提高自定义异常,请使用:

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

This keeps your Exception code simple and allows you to distinguish between those exceptions: 这使您的Exception代码变得简单,并允许您区分这些异常:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM