为什么if语句有效但不是switch语句

And*_*ewE 39 c# if-statement switch-statement

我正在尝试switch使用字符串的char索引和使用包装器的Enum 创建语句,以从描述中获取所选枚举的值.它几乎允许您将字符串存储到枚举值.

这是我的if发言:

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

这是我的switch发言:

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

为什么接受if声明而不是switch?我尝试将它转换为char,因为我从字符串中选择索引,但不幸的是它没有用.

更新:

这是Message.CodeEnum

public class Message
{
    public enum Code
    {
        [Description("A")]
        FOO_TRIGGER_SIGNAL
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我需要分配给枚举不枚举值是0.使用说明Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()自提包装回报A0


错误:

期望一个恒定的价值

Pol*_*fun 53

你不能在这种情况下使用表达式(在C#7之前),但你可以在交换机中,所以这将工作:

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

你需要写ConvertToMessageCode的地方做必要的转换到Message.Code枚举.ConvertToMessageCode只是抽象转换细节,您可能会发现您不需要单独的方法,但可以使用switch语句中的内联代码,例如强制转换.

  • 其历史原因是K&R C中`switch`语句的原始概念是[Jump Table](https://en.wikipedia.org/wiki/Branch_table)的高级表达. (7认同)
  • 您[可以在C#7中使用表达式](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/when#when-in-a-switch-statement) - 但我同意这个答案中的建议是更好的设计. (6认同)

Cod*_*ice 27

一个caseswitch语句必须引用一个恒定值.你无法评估一个表达式case.

  • 如何在进行切换之前将msgComingFromFoo [1]转换为枚举值 (3认同)

Joc*_*ers 6

这真的不是一个好的答案,因为它仅用作以前答案的详细说明.不要接受它(请不要在任何合理的答案之上投票).我正在写它作为答案,因为评论不适合这种解释.


你试过:

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

这不起作用,因为案例不是一成不变的.正如所建议的那样,最好的方法是将msgComingFromFoo[1]字符串转换回枚举值,以便切换枚举并在切换案例中使用枚举常量.

如果这在某种程度上是不可能的,您可以随时切换字符串常量.但是,这很容易出错,并且首先失败了使用枚举的目的.

switch (msgComingFromFoo[1])
{
    case "A":
        break;
}
Run Code Online (Sandbox Code Playgroud)

另一句话:记住数组是零索引的.您目前正在切换第二个元素,而不是第一个元素.使用msgComingFromFoo[0]的第一个元素.


Vic*_*ure 5

添加到@ 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);
 }
Run Code Online (Sandbox Code Playgroud)

访客模式