Почему оператор if работает, но не оператор switch

Я пытаюсь создать оператор switch используя индекс char строки и Enum, используя эту оболочку, чтобы получить значение выбранного перечисления из Description. Это в значительной степени позволяет вам сохранить строку до значения enum.

Вот мое выражение if:

if (msgComingFromFoo[1] == Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()))
{
    //foo
}

и вот мое выражение о switch:

switch (msgComingFromFoo[1])
{
    case Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()):
        break;
}

Почему он принимает оператор if а не switch? Я попытался преобразовать его в символ, так как я выбираю индекс из строки, но, к сожалению, это не сработало.

Обновить:

Вот Message.Code Enum

public class Message
{
    public enum Code
    {
        [Description("A")]
        FOO_TRIGGER_SIGNAL
    }
}

Как видите, мне нужно, чтобы описание, присвоенное перечислению, а не значение перечисления, равное 0. Использование Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString() из упомянутой оболочки возвращает A не 0


Ошибка:

Ожидается постоянное значение

Ответ 1

Вы не можете иметь выражения в случае (до С# 7), но вы можете в переключателе, так что это будет работать:

switch (ConvertToMessageCode(msgComingFromFoo[1]))
{
    case Message.Code.FOO_TRIGGER_SIGNAL:
        break;
}

Где вам нужно будет написать ConvertToMessageCode чтобы выполнить необходимое преобразование в перечисление Message.Code. ConvertToMessageCode просто абстрагирует детали преобразования, вы можете обнаружить, что вам не нужен отдельный метод, но он может обойтись с встроенным кодом в операторе switch, например, приложением.

Ответ 2

case в инструкции switch должен ссылаться на постоянное значение. Вы не можете оценить выражение в case.

Ответ 3

Это действительно не очень хороший ответ, поскольку он служит только для разработки предыдущих ответов. Не принимайте его (пожалуйста, также не поднимайте над любым разумным ответом). Я пишу это как ответ только потому, что комментарий не будет соответствовать этому объяснению.


Ты пытался:

switch (msgComingFromFoo[1])
{
    case Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()):
        break;
}

Это не работает, поскольку случай не является постоянным. Как и было предложено, наилучшим способом перевести msgComingFromFoo[1] обратно в значение перечисления, чтобы вы могли переключить перечисление и использовать константы перечисления в случаях переключения.

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

switch (msgComingFromFoo[1])
{
    case "A":
        break;
}

Еще одно замечание: помните, что массивы нулевые индексируются. Вы в настоящее время переключаете второй элемент, а не первый. Используйте msgComingFromFoo[0] для первого элемента.

Ответ 4

Чтобы добавить к ответу @code-apprentice.

Если вы обнаруживаете, что оператор if становится слишком длинным или имеет несколько условий внутри, if else. Вы можете посмотреть рефакторинг кода и инкапсулировать свою логику в объект и использовать шаблон посетителя, чтобы контролировать выполняемую работу.

Что-то вроде:

public interface IMessageLogic 
{
   void ProcessMessage()
}

public class TriggerSignal : IMessageLogic 
{
   public void ProcessMessage() 
   {
       // Do trigger stuff
   }
}

public class FooMessage : IMessageLogic 
{
   public void ProcessMessage() 
   {
       // Do foo stuff
   }
}

public class MessageHandler
{
    public void HandleMessage(IMessageLogic messageLogic)
    {
        messageLogic.ProcessMessage();
    }
}

public static void Main()
{
    IMessageLogic messageLogic = GetMessage();
    var handler = new MessageHandler();

    handler.HandleMessage(messageLogic);
 }

Шаблон посетителя