计算 C # 中 Switch 语句中的表达式

我必须在 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? 如果没有,我怎么能做到这一点?

115326 次浏览

注意: 下面的答案是在2009年写的。开关模式是在 C # 7中引入的。


如果你想指定条件,你需要一个“如果”:

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

不管你愿不愿意,你都得用。Switch 只能将您的值与常数值进行比较。

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

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。

我能想到的唯一方法(我真的不推荐)是这样的:

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;
}

你可以在 switch 语句的末尾做这样的操作:

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

反过来也是可能的(关于 Jon Skeet 的回答) :

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

你不能像在 VB 中那样在开关中使用比较,这里有两个选项,用一个已知的值替换你打开的值,然后使用它,或者——如果你指的是所有其他情况——你可以使用默认子句:

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

请注意,这并不完全符合您的要求: 除了0、3、4之外的任何值都将最终出现在 default: 子句中。

我知道这个话题已经很老了,但是如果有人现在仍然在 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;
}

您可以使用这样的委托。

        var actionSwitch = new Dictionary<Func<int, bool>, Action>
{
{ x => x < 0 ,     () => Log.Information("less than zero!")},
{ 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 版本的交换机,我刚刚写了一个 博客文章与切换示例章

但是如果你能使用 C # 7,它会给你 更好的转换能力

你能做到的

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;
}

我最近遇到了下面这种情况,虽然我对此深恶痛绝,但我不能说它不切实际:

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:
...
}

在 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 设置为 Latest 或9.0

例如:。

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

输入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"
};

砰。

(公平地说,转换表达式是 C # 8.0的特性,所以不是真正的2021。但似乎仍然很少有人知道这件事。)