пользовательские - типы исключений c#




Просить общий метод бросить конкретный тип исключения на FAIL (4)

Правильно, я знаю, что я полностью буду выглядеть идиотом с этим, но мой мозг просто не пинает сегодня утром.

Я хочу иметь метод, где я могу сказать «если это плохо, вернитесь с этим типом исключения», правильно?

Например, что-то вроде ( и это не работает ):

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = new Exception(message);
        return ex;
    }

Теперь что нас смущает, так это то, что мы ЗНАЕМ, что общий тип будет иметь тип исключения из-за предложения where . Однако код выходит из строя, потому что мы не можем неявно использовать Exception для ExType . Мы также не можем его явно преобразовать, например:

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = (ExType)(new Exception(message));
        return ex;
    }

Поскольку это терпит неудачу ... Так возможно ли это? У меня есть сильное чувство, что это будет очень просто, но у меня тяжелый день со старым ноггином, так что я немного оборвал: P

Обновить

Спасибо за ответы, ребята, похоже, я не был полным идиотом! ;)

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

Мэтт ударил ноготь прямо по голове своим ответом, я проверил это, и все работает нормально. Вот пример кода:

    static ExType TestException<ExType>(string message) where ExType:Exception, new ()
    {
        ExType ex = (ExType)Activator.CreateInstance(typeof(ExType), message);
        return ex;
    }

Милая! :)

Спасибо, парни!


Вы можете сделать это примерно так:

static void TestException<E>(string message) where E : Exception, new()
{
    var e = new E();
    e.Message = message;
    throw e;
}

Однако это не компилируется, потому что Exception.Message только для чтения. Он может быть назначен только путем передачи его конструктору, и нет никакого способа ограничить общий тип чем-то другим, кроме конструктора по умолчанию.

Я думаю, вам придется использовать отражение (Activator.CreateInstance) для «нового» настраиваемого типа исключения с параметром сообщения, например:

static void TestException<E>(string message) where E : Exception
{
    throw Activator.CreateInstance(typeof(E), message) as E;
}

Редактировать К сожалению, вы поняли, что хотите вернуть исключение, а не бросать его. Тот же принцип применяется, поэтому я оставлю свой ответ как есть с заявлениями о выбросах.


Вы попробовали, вместо этого:

static T TestException<Exception>(string message)
{}

потому что у меня возникает ощущение, что вложение общего ограничения не требуется, поскольку все бросающиеся исключения должны наследовать от System.Exception в любом случае.

Помните, что дженерики действительно принимают унаследованные типы.


Я думаю, что все исключения должны иметь конструктор без параметров и иметь свойство Message , поэтому следующее должно работать:

static ExType TestException<ExType>(string message) where ExType:Exception
{
    ExType ex = new ExType();
    ex.Message = message;
    return ex;
}

Изменить: ОК, сообщение читается только, поэтому вам придется надеяться, что класс реализует конструктор Exception (string).

static ExType TestException<ExType>(string message) where ExType:Exception
{
    return new ExType(message);
}

Я создавал встроенный тип исключения, который я хочу бросить, например:

if (ItemNameIsValid(ItemName, out errorMessage))
    throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
    throw new ArgumentNullException("MyArgument is null");




exception