Запрос универсального метода для выдачи определенного типа исключения при FAIL

StackOverflow https://stackoverflow.com/questions/41397

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

    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;
}

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

Другие советы

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

static void TestException<E>(string message) where E : Exception, new()
{
    try 
    {
      return Activator.CreateInstance(typeof(E), message) as E;
    } 
    catch(MissingMethodException ex) 
    {
      return new E();
    }
}

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

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

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

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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top