значение ожидаемого переключения интегрального типа с динамическим параметром

Просто из любопытства.

Если у меня есть следующий код

public static string Format(dynamic exception)
{
    switch (exception.GetType().ToString())
    {
        case "test":
            return "Test2";
    }
    return null;
}

я получаю сообщение об ошибке "Выражение переключения или метка case должны быть типа bool, char, string, integer, enum или соответствующего типа, допускающего значение NULL"

но если у меня есть следующий код

public static string Format(dynamic exception)
{
    string test = exception.GetType().ToString();
    switch (test)
    {
        case "test":
            return "Test2";
    }
    return null;
}

все нормально компилируется. Какая разница, если переключатель проверяет переменную типа string и ToString()? Или это из-за шанса вызвать исключение до вызова ToString()?


person Belial09    schedule 14.02.2014    source источник


Ответы (2)


Я считаю, что проблема в том, что ваша переменная exception является объектом dynamic. Поскольку он динамический, его тип не разрешается во время компиляции, равно как и типы каких-либо методов, вызываемых для него.

Таким образом, оператор switch в первом случае не знает, какой тип вернет метод .GetType() или метод .ToString(). Если вы хотите, чтобы это работало, вы можете использовать его, например:

switch (exception.GetType().ToString() as string)

Во втором блоке кода вы явно указываете, что результатом exception.GetType().ToString() будет строка. В этом случае компилятор знает тип переменной, передаваемой оператору switch.

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

Глядя на содержимое вашей функции Format, вы могли бы добиться той же функциональности, если бы передали exception как object. Если вы используете эту функцию для форматирования Exceptions, лучше всего использовать Exception в качестве типа параметра exception.

person Jon Senchyna    schedule 14.02.2014

Я нашел этот вопрос после рефакторинга метода и нашел ту же ошибку,

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

  var action = Utilities.ConvertAction(x.action);
  switch (action)
  {
            case GridActions.ADD:
              MethodX();
              break;
            case GridActions.UPDATE:
              MethodX();
              break;
            case GridActions.DELETE:
              MethodX();
              break;
            default: throw new WebException("Invalid action.");
  }

поскольку в методе ConvertAction есть исключение throw, которое коммутатор не выполняет, это было решено путем жесткого ввода action, ошибка была устранена:

  GridActions action = Utilities.ConvertAction(x.action);
  switch (action)
  {
            case GridActions.ADD:
              MethodX();
              break;
            case GridActions.UPDATE:
              MethodX();
              break;
            case GridActions.DELETE:
              MethodX();
              break;
            default: throw new WebException("Invalid action.");
  }
person Ymnia    schedule 23.10.2014
comment
Я предполагаю, что ваша проблема связана с тем, что Utilities.ConvertAction не возвращает GridActions, а скорее какой-то другой тип. var строго типизирован; он просто выводит свой тип из присваивания. - person Jon Senchyna; 31.10.2014