在C#中评估交换机语句中的表达式

时间:2009-10-12 13:48:15

标签: c# switch-statement

我必须在switch声明中实现以下内容:

switch(num)
{
  case 4:
    // some code ;
    break;
  case 3:
    // some code ;
    break;
  case 0:
    // some code ;
    break;
  case < 0:
    // some code ;
    break;
}

是否可以让switch语句评估case < 0?如果没有,我怎么能这样做?

13 个答案:

答案 0 :(得分:68)

你不能 - 开关/案例仅适用于个别值。如果要指定条件,则需要“if”:

if (num < 0)
{
    ...
}
else
{
    switch(num)
    {
        case 0: // Code
        case 1: // Code
        case 2: // Code
        ...
    }
}

答案 1 :(得分:32)

我知道这个话题已经很老了,但是如果现在仍然有人在C#7中寻找答案,那么这是可能的。这是一个例子:

switch (value)
{
     case var expression when value < 0:
         //some code
         break; 

     case var expression when (value >= 0 && value < 5):
         //some code
         break;

     default:
         //some code
         break;
}

答案 2 :(得分:13)

你可以在switch语句的末尾执行类似的操作:

default:
    if(num < 0)
    {
        ... // Code
    }
    break;

答案 3 :(得分:8)

如果你的数字不能小于零:

public int GetSwitch(int num) { return num < 0 ? -1 : num; }
switch(GetSwitch(num))
{
case 4: // some code ; break;
case 3:// some code ; break;
case 0: // some code ; break;
case -1 :// some code ; break;
}

如果可以,请使用其他“不存在”的数字,例如int.MinValue。

答案 4 :(得分:5)

无论您是否愿意,都必须使用if。 Switch只能将您的值与常量值进行比较。

答案 5 :(得分:5)

我能想到的唯一方法(我真的不推荐它)如下:

int someValue;

switch (Math.Max(someValue, -1))
{
    case -1:
        // will be executed for everything lower than zero.
        break;

    case 0:
       // will be executed for value 0.
       break;

    case 1:
       // will be executed for value 1.
       break;

    default:
       // will be executed for anything else.
       break;
}

答案 6 :(得分:4)

另一种方式也是可能的(与Jon Skeet的答案有关):

switch(num)
{
  case a:
      break;
  default:
      if( num < 0 )
      {}
   break;
}

答案 7 :(得分:4)

进入 2021 年。

var res = num switch
{
    4 => "It's four",
    3 => "It's three",
    0 => "It's zero",
    < 0 => "It's negative",
    _ => "It's something else"
};

繁荣。

(公平地说,switch expressions 是 C# 8.0 的一个特性,所以不是真正的 2021。但似乎仍然很少有人知道它。)

答案 8 :(得分:3)

你可以做到

switch (mark)
        {
            case int n when n >= 80:
                Console.WriteLine("Grade is A");
                break;

            case int n when n >= 60:
                Console.WriteLine("Grade is B");
                break;

            case int n when n >= 40:
                Console.WriteLine("Grade is C");
                break;

            default:
                Console.WriteLine("Grade is D");
                break;
        }

答案 9 :(得分:2)

你可以做的就是使用这样的代表。

        var actionSwitch = new Dictionary<Func<int, bool>, Action>
        {
             { x => x < 0 ,     () => Log.Information("0")},
             { x => x == 1,     () => Log.Information("1")},
             { x => x == 2,     () => Log.Information("2")},
             { x => x == 3,     () => Log.Information("3")},
             { x => x == 4,     () => Log.Information("4")},
             { x => x == 5,     () => Log.Information("5")},
        };

        int numberToCheck = 1;

        //Used like this
        actionSwitch.FirstOrDefault(sw => sw.Key(numberToCheck)).Value();

只需将你想要执行的内容换成Log.Information(“x”)并且你有“switch”语句。

如果检查Func“找到”的密钥,则需要进行一些错误处理。

如果您想查看交换机的Func版本,我刚写了blog post with Switch example chapter

答案 10 :(得分:2)

在 C# 命运的转折中,这又回来了。如果你升级到 C# 9.0,你原来的 switch 语句现在可以编译了! C#9.0 在一般模式匹配中添加了关系模式,包括 switch 语句。

您现在可以做一些非常时髦的事情,例如:

      var num = new Random().Next();
      
      switch(num)
      {
        case < 0:
          // some code ;
          break;
        case 0:
          // some code ;
          break;
        case > 0 and < 10:
          // some code ;
          break;
        case > 20 or (< 20 and 15):
          // some code ;
          break;
      }

注意在最后一种情况下使用文字“and”和“or”,以允许 && 和 ||键入要编译的表达式。

要使用 C# 9,请确保在 csproj 文件的属性组中将 XmlNode LangVersion 设置为最新或 9.0

例如

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <Platforms>AnyCPU;x86</Platforms>
    <Configurations>Debug;Release;Mock</Configurations>
    <LangVersion>Latest</LangVersion>
  </PropertyGroup>

答案 11 :(得分:1)

你不能像在VB中那样在开关中使用比较,你有2个选项,用你已知的值替换你打开的值并使用它或 - 如果你的意思是所有其他情况 - 你可以使用默认子句:

switch(num)
{
  case 4:
    // some code ;
    break;
  case 3:
    // some code ;
    break;
  case 0:
    // some code ;
    break;
  default:
    // some code ;
    break;
}

请注意,这与您要求的不完全相同:0,3,4以外的任何值都将以deafult:子句结束。

答案 12 :(得分:0)

我最近遇到了以下模式,尽管我对此表示厌恶,但我不能认为它是不实际的:

switch(0)
{
  case 0 when x < 0:
    ...
    break;
  case 0 when a > 5 && x == 0:
    ...
    break;
}

使用伪表达式(开关中的(0)case 0)是绝对可怕的,我不希望它成为一种习惯用法,但是,嘿-简洁明了。可以肯定的是,并不是完全掩盖了含义并需要奥术知识的技巧。但是C#可以很好地消除它的需要。我希望以下内容合法:

switch                   // maybe () here, if the grammar would demand
{
  case when x < 0:       // I like the case to stay
    ...
  case when a > 5 && x == 0:
    ...
}