Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在switch语句中使用字符串集合_C#_Arrays_String_Switch Statement - Fatal编程技术网

C# 在switch语句中使用字符串集合

C# 在switch语句中使用字符串集合,c#,arrays,string,switch-statement,C#,Arrays,String,Switch Statement,我正试图找到解决这个问题的办法。这是我的示例代码: class Program { private string Command; private static string[] Commands = { "ComandOne", "CommandTwo", "CommandThree", "CommandFour" }; static void Main(string[] args) { Command = args[0]; switch(Command)

我正试图找到解决这个问题的办法。这是我的示例代码:

class Program
{
  private string Command;

  private static string[] Commands = { "ComandOne", "CommandTwo", "CommandThree", "CommandFour" };


  static void Main(string[] args)
  {
    Command = args[0];
    switch(Command)
    {
      case Commands[0]: //do something 
        break;
      case Commands[1]: //do something else
        break;
      case Commands[2]: //do something totally different
        break;
      case Commands[3]: //do something boring
        break;
      default: //do your default stuff
        break;
    }
  }

  void DifferentMethod()
  {
    foreach(string c in Commands)
    {
      //do something funny
    }
  }
}
此代码不起作用,因为开关中的字符串值不是常量。我想编写易于维护的代码。
我喜欢使用数组之类的东西,因为我需要在循环中的其他地方使用相同的值。

对于int值,枚举是完美的,但是对于字符串,我没有找到一个小的解决方案

正如您所说,开关中只允许使用常量表达式。通常,您可以通过定义
enum
并在交换机中使用它来实现这一点

class Program
{
  private enum Command
  {
    CommandOne = 1,
    CommandTwo = 2,
    CommandThree = 3
  }

  static void Main(string[] args)
  {
    var command = Enum.Parse(typeof(Commands), args[0]);
    switch(command )
    {
      case Command.CommandOne: //do something 
        break;
      case Command.CommandTwo: //do something else
        break;
      case Command.CommandThree: //do something totally different
        break;
      default: //do your default stuff
        break;
    }
  }
}

使用
Enum.GetValues
DifferentMethod
中通过枚举值进行枚举就在昨天,我为它创建了一个解决方案。在您的情况下,
enum
s更好,但这里是我针对一般非常量切换情况的解决方案

用途:

    static string DigitToStr(int i)
    {
        return i
            .Case(1, "one")
            .Case(2, "two")
            .Case(3, "three")
            .Case(4, "four")
            .Case(5, "five")
            .Case(6, "six")
            .Case(7, "seven")
            .Case(8, "eight")
            .Case(9, "nine")
            .Default("");
    }

        int a = 1, b = 2, c = 3;
        int d = (4 * a * c - b * 2);
        string res = true
            .Case(d < 0, "No roots")
            .Case(d == 0, "One root")
            .Case(d > 0, "Two roots")
            .Default(_ => { throw new Exception("Impossible!"); });

        string res2 = d
            .Case(x => x < 0, "No roots")
            .Case(x => x == 0, "One root")
            .Case(x => x > 0, "Two roots")
            .Default(_ => { throw new Exception("Impossible!"); });

        string ranges = 11
            .Case(1, "one")
            .Case(2, "two")
            .Case(3, "three")
            .Case(x => x >= 4 && x < 10, "small")
            .Case(10, "ten")
            .Default("big");
静态字符串digittost(int i)
{
返回i
.案例(1,“一”)
.案例(2,“两个”)
.案例(3,“三”)
.案例(4,“四”)
.案例(5,“五”)
.案例(6,“六”)
.案例(7,“七”)
.案例(8,“八”)
.案例(9,“9”)
.违约(“”);
}
INTA=1,b=2,c=3;
int d=(4*a*c-b*2);
字符串res=true
.情况(d<0,“无根”)
.Case(d==0,“一个根”)
.情况(d>0,“两个根”)
.Default({throw new Exception(“不可能!”);});
字符串res2=d
.Case(x=>x<0,“无根”)
.Case(x=>x==0,“一个根”)
.Case(x=>x>0,“两个根”)
.Default({throw new Exception(“不可能!”);});
字符串范围=11
.案例(1,“一”)
.案例(2,“两个”)
.案例(3,“三”)
.Case(x=>x>=4&&x<10,“小”)
.案例(10,“十”)
.违约(“大”);
定义:

class Res<O, R>
{
    public O value;
    public bool succ;
    public R result;

    public Res()
    {

    }

    static public implicit operator R(Res<O, R> v)
    {
        if (!v.succ)
            throw new ArgumentException("No case condition is true and there is no default block");
        return v.result;
    }
}

static class Op
{
    static public Res<O, R> Case<O, V, R>(this Res<O, R> o, V v, R r)
    {
        if (!o.succ && Equals(o.value, v))
        {
            o.result = r;
            o.succ = true;
        }
        return o;
    }

    static public Res<O, R> Case<O, V, R>(this O o, V v, R r)
    {
        return new Res<O, R>()
        {
            value = o,
            result = r,
            succ = Equals(o, v),
        };
    }

    static public Res<O, R> Case<O, R>(this Res<O, R> o, Predicate<O> cond, R r)
    {
        if (!o.succ && cond(o.value))
        {
            o.result = r;
            o.succ = true;
        }
        return o;
    }

    static public Res<O, R> Case<O, R>(this O o, Predicate<O> cond, R r)
    {
        return new Res<O, R>()
        {
            value = o,
            result = r,
            succ = cond(o),
        };
    }

    private static bool Equals<O, V>(O o, V v)
    {
        return o == null ? v == null : o.Equals(v);
    }

    static public R Default<O, R>(this Res<O, R> o, R r)
    {
        return o.succ
            ? o.result
            : r;
    }

    static public R Default<O, R>(this Res<O, R> o, Func<O, R> def)
    {
        return o.succ ? o.result : def(o.value);
    }
}
class-Res
{
公共价值观;
公共事业成功;
公共关系结果;
公共资源()
{
}
静态公共隐式运算符R(Res v)
{
如果(!v.succ)
抛出新ArgumentException(“没有case条件为true,并且没有默认块”);
返回v.result;
}
}
静态类Op
{
静态公共资源案例(此资源o、V、R)
{
如果(!o.such&&Equals(o.value,v))
{
o、 结果=r;
o、 成功=正确;
}
返回o;
}
静态公共资源案例(此O O、V、R)
{
返回新的Res()
{
值=o,
结果=r,
succ=等于(o,v),
};
}
静态public Res Case(此Res o,谓词cond,R)
{
如果(!o.such&&cond(o.value))
{
o、 结果=r;
o、 成功=正确;
}
返回o;
}
静态public Res Case(此O O,谓词cond,R)
{
返回新的Res()
{
值=o,
结果=r,
成功=秒(o),
};
}
私有静态布尔等于(O,V)
{
返回o==null?v==null:o.Equals(v);
}
静态公共R默认值(此资源o,R)
{
成功返回
?o.结果
:r;
}
静态公共R默认值(此Res o,Func def)
{
返回o.succ?o.result:定义(o.value);
}
}

定义一个
字典
,并在输入开关之前将输入命令映射到适当的值。如果未找到匹配项,则会进行默认处理。

命令转换为枚举:

enum Commands { ComandOne, CommandTwo, CommandThree, CommandFour }
Switch语句应该如下所示:

static void Main(string[] args)
{
    Command = (Commands)Enum.Parse(typeof(Commands), args[0]);
    switch(Command)
    {
        case Commands.CommandOne: 
            //do something 
            break;
        case Commands.CommandTwo: 
            //do something else
            break;
        ...
        default:
            // default stuff
    }
}
void DifferentMethod()
{
    foreach(var c in Enum.GetValues(typeof(Commands)))
    {
        string s = c.ToString(); 
        //do something funny
    }
}
最后一种方法应该如下所示:

static void Main(string[] args)
{
    Command = (Commands)Enum.Parse(typeof(Commands), args[0]);
    switch(Command)
    {
        case Commands.CommandOne: 
            //do something 
            break;
        case Commands.CommandTwo: 
            //do something else
            break;
        ...
        default:
            // default stuff
    }
}
void DifferentMethod()
{
    foreach(var c in Enum.GetValues(typeof(Commands)))
    {
        string s = c.ToString(); 
        //do something funny
    }
}
具体示例中的一个简单修复:

其他备选方案:

  • 内联字符串

    开关(命令) { 案例“CommandOne”:。。。 案例二:。。。 }

  • 正如KirkWoll所说,使用枚举代替。这可能是最干净的解决方案

  • 在更复杂的场景中,使用诸如
    Dictionary
    Dictionary
    之类的查找可能会提供更好的表达能力

  • 如果情况复杂,您可以创建一个
    ICommand
    接口。这将需要将命令字符串映射到正确的具体实现,为此,您可以使用简单的构造(开关/字典)或奇特的反射(查找具有该名称的
    ICommand
    实现,或使用特定的属性装饰)


  • 你可以通过另一种方式来实现你的目标

    使用Enum及其GetNames调用获取要循环的字符串数组

    Enum.GetNames(typeof (*YOURENUM*));
    

    更多信息

    这里的答案很好,可能比我要提到的更好地回答了你的问题

    根据你的逻辑是多么复杂,你可以考虑使用这样的策略模式:


    同样,很可能比您的解决方案所要求的更复杂,只需将其扔到那里…

    您可以通过创建
    IYourCommand
    对象并将其加载到
    字典中,从而完全消除
    switch
    语句

    类程序
    {
    专用字典命令=新建字典
    {
    {“CommandOne”,新CommandOne()},
    {“CommandTwo”,新CommandTwo()},
    {“CommandThree”,新CommandThree()},
    {“CommandFour”,新CommandFour()},
    };
    公共静态void Main(字符串[]args)
    {
    if(Command.ContainsKey(args[0]))
    {
    命令[args[0]].DoSomething();
    }
    }
    }
    公共接口命令
    {
    无效剂量();
    }
    
    我通常不喜欢这种类型的字符串-拼写错误、不同的大小写等很容易造成麻烦-但这大概就是为什么要使用变量而不是字符串文字。如果枚举解决方案不合适,请使用c
    class Program
    {
        private string Command;
    
        const string command1 = "CommandOne";
        const string command2 = "CommandTwo";
        const string command3 = "CommandThree";
        const string command4 = "CommandFour";
    
        private static string[] Commands = { command1, command2, command3, command4 };
    
        static void Main(string[] args)
        {
            string Command = args[0];
            switch (Command)
            {
                case command1: //do something 
                    break;
                case command2: //do something else
                    break;
                case command3: //do something totally different
                    break;
                case command4: //do something boring
                    break;
                default: //do your default stuff
                    break;
            }
        }
    
        void DifferentMethod()
        {
            foreach (string c in Commands)
            {
                //do something funny
            }
        }
    }