Почему оператор 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);
}
Шаблон посетителя