【问题标题】:Switch statement with static fields带有静态字段的 switch 语句
【发布时间】:2012-09-07 22:32:28
【问题描述】:

假设我有一堆静态字段,我想在 switch 中使用它们:

public static string PID_1 = "12";
public static string PID_2 = "13";
public static string PID_3 = "14";

switch(pid)
{
    case PID_1:
        //Do something 1
        break;
    case PID_2:
        //Do something 2
        break;
    case PID_3:
        //Do something 3
        break;
    default:
        //Do something default
        break;
}

由于 C# 不允许在 switch 中使用非常量语句。我想了解这种设计的意图是什么。我应该如何在 c# 中执行上述操作?

【问题讨论】:

  • PID_1 PID_2 etc的值会改变吗?
  • 明多先生。不,但我也希望它们是静态的。
  • @Ashutosh 所有const 值实际上都是static。它们不依赖于类的实例。您不使用 static 是因为它是多余的,而不是因为它不可能。

标签: c# .net static switch-statement


【解决方案1】:

看起来那些字符串值应该只是常量。

public const string PID_1 = "12";
public const string PID_2 = "13";
public const string PID_3 = "14";

如果这不是一个选项(它们实际上是在运行时更改的),那么您可以将该解决方案重构为一系列 if/else if 语句。

关于为什么 case 语句需要保持不变;通过让它们保持不变,可以对语句进行更多优化。它实际上比一系列 if/else if 语句更有效(尽管如果您没有 lots 需要很长时间的条件检查,效果并不明显)。它将生成一个等效的哈希表,其中 case 语句的值作为键。如果值可以更改,则无法使用该方法。

【讨论】:

  • 好的。那么为什么我们不能使用只读字段呢?使用 const 不是一种选择。拥有一个公共静态对于常量标识符更有意义。我不能在任何我想要的地方使用它们,我只有一个实例......
  • @Ashutosh 您不能使用只读字段,因为该值直到运行时才知道; switch 语句将导致在编译时生成一个表,这就是为什么 case 语句都需要是编译时常量的原因。 "Having a public static makes more sense" 如果这些值实际上是恒定的,我不同意。如果值实际上是恒定的,则使用 const 值会更有意义。请注意,所有const 值实际上都是static。它们根本不绑定到对象的实例。
【解决方案2】:

Case 参数在编译时应保持不变。

尝试改用const

public const string PID_1 = "12";
public const string PID_2 = "13";
public const string PID_3 = "14";

【讨论】:

    【解决方案3】:

    ...C# 不允许在 switch 中使用非常量语句...

    如果不能使用:

    public const string PID_1 = "12";
    public const string PID_2 = "13";
    public const string PID_3 = "14";
    

    你可以使用字典:)

    ....
    public static string PID_1 = "12";
    public static string PID_2 = "13";
    public static string PID_3 = "14";
    
    
    
    // Define other methods and classes here
    
    void Main()
    {
       var dict = new Dictionary<string, Action>
       {
        {PID_1, ()=>Console.WriteLine("one")},
        {PID_2, ()=>Console.WriteLine("two")},
        {PID_3, ()=>Console.WriteLine("three")},
       };
       var pid = PID_1;
       dict[pid](); 
    }
    

    【讨论】:

      【解决方案4】:

      我假设您没有将这些变量声明为 const 是有原因的。也就是说:

      switch 语句只是一堆if / else if 语句的简写。因此,如果您可以保证PID_1PID_2PID_3永远相等,则以上等价于:

      if (pid == PID_1) {
          // Do something 1
      }
      else if (pid == PID_2) {
          // Do something 2
      }
      else if (pid == PID_3) {
          // Do something 3
      }
      else {
          // Do something default
      }
      

      【讨论】:

      【解决方案5】:

      解决此问题的规范方法(如果您的静态字段实际上不是常量)是使用Dictionary&lt;Something, Action&gt;

      static Dictionary<string, Action> switchReplacement = 
          new Dictionary<string, Action>() {
              { PID_1, action1 }, 
              { PID_2, action2 }, 
              { PID_3, action3 }};
      
      // ... Where action1, action2, and action3 are static methods with no arguments
      
      // Later, instead of switch, you simply call
      switchReplacement[pid].Invoke();
      

      【讨论】:

        【解决方案6】:

        为什么不使用枚举?
        枚举关键字:
        http://msdn.microsoft.com/en-us/library/sbbt4032%28v=vs.80%29.aspx

        在您的情况下,它可以通过枚举轻松处理:

        public enum MyPidType
        {
          PID_1 = 12,
          PID_2 = 14,
          PID_3 = 18     
        }
        

        【讨论】:

          【解决方案7】:

          我知道这是一个老问题,但有一种方法未包含在其他不涉及更改方法的答案中:

          switch(pid)
          {
             case var _ when pid == PID_1:
                //Do something 1
             break;
          }
          

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-18
          • 1970-01-01
          相关资源
          最近更新 更多