Есть ли способ бросить специальное исключение без класса Exception

Есть ли какой-либо способ в С# (т.е. в .NET), чтобы создать настраиваемое исключение, но без написания всего кода для определения вашего собственного класса исключения, полученного из Exception?

Я думаю что-то подобное у вас есть, например, в Oracle PL/SQL, где вы можете просто написать

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

в любом месте.

Ответы

Ответ 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!");

может работать.

Обратите внимание, что вам должно быть не throw new ApplicationException(), за MSDN.

Основной недостаток несоблюдения Исключения заключается в том, что вызывающим абонентам будет сложнее поймать - они не будут знать, было ли это общее исключение или специфическое для вашего кода, без какой-либо фанковой проверки исключения. Свойство сообщения. Вы можете сделать что-то простое:

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

чтобы избежать этого.

Обновление: Visual Studio 2015 теперь предлагает некоторую автоматическую реализацию классов расширения Exception - если вы откроете меню быстрых действий и рефакторинга с помощью курсора на : Exception, просто скажите "Generate All" Конструкторы".

Ответ 2

Короткий ответ - нет.

Существует хорошая причина для принудительного наследования пользовательских исключений; люди должны уметь справляться с ними. Если вы можете отправить свое собственное исключение без типа, люди не смогут поймать этот тип исключения.

Если вы не хотите писать настраиваемое исключение, используйте существующий тип исключения.

Ответ 3

Класс Exception не является abstract и, как и большинство исключений, определенных в .NET, принимает string message в одной из перегрузок конструктора - поэтому вы можете использовать существующий тип исключения, но с индивидуальное сообщение.

throw new Exception("Something has gone haywire!");
throw new InvalidOperationException("He Dead, Jim");
throw new InvalidCastException(
    string.format("Damnit Jim I'm a {0}, not a {1}!",
        a.GetType().Name, b.GetType().Name));

Поскольку это использует известные типы исключений, это упрощает тем, чтобы сторонние стороны также расширяли ваши библиотеки, поскольку они не нуждаются в поиске MyArbitraryException в операторах catch.

Ответ 4

Вы можете просто выбросить одно из исключений, которое доступно в .NET:

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

Или более общий:

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

Ответ 5

Простым способом создания пользовательских исключений в С# является общий класс. Это значительно сокращает количество строк кода, если вам нужно создать много исключений (т.е. Если вам нужно различать их в своих модульных тестах).

Сначала создайте простой класс 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 ...
}