【问题标题】:Why is an if statement working but not a switch statement为什么 if 语句有效但 switch 语句无效
【发布时间】:2018-07-31 14:11:07
【问题描述】:

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

这是我的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?由于我从字符串中选择索引,因此我尝试将其转换为 char,但不幸的是它不起作用。

更新:

这是Message.Code枚举

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

如您所见,我需要分配给枚举的描述而不是枚举值 0。使用提到的包装器中的 Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString() 返回 A 而不是 0


错误:

需要一个常数值

【问题讨论】:

  • 请在问题中包含您使用 switch 语句得到的错误。
  • 虽然您已接受答案,但我们仍需要您将错误添加到问题中以供未来访问者使用。目前你只是说“它不起作用”,这不是一个好问题。

标签: c# if-statement switch-statement


【解决方案1】:

您不能在 case 中使用表达式(在 C# 7 之前),但您可以在 switch 中使用,所以这将起作用:

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

您需要在哪里写 ConvertToMessageCode 以进行必要的转换为 Message.Code 枚举。 ConvertToMessageCode 只是抽象了转换细节,你可能会发现你不需要单独的方法,而是可以在 switch 语句中使用内联代码,例如强制转换。

【讨论】:

【解决方案2】:

switch 语句中的case 必须引用一个常量值。您不能评估 case 中的表达式。

【讨论】:

  • @AndrewE 一种可能的解决方案是重新设计您的代码,以便您可以直接切换枚举值而不是描述字符串。
  • 在切换之前如何将 msgComingFromFoo[1] 转换为枚举值
【解决方案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);
     }
    

    Visitor Pattern

    【讨论】:

      猜你喜欢
      • 2019-12-11
      • 1970-01-01
      • 2012-05-14
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 2016-03-02
      • 1970-01-01
      相关资源
      最近更新 更多