我可以像这样用c#编写switch case吗?
switch (string)
case [a..z]+
// do something
case [A..Z]+
// do something
....
是的,在 C# 7 中可以(并且没有人注意到我在字符类
..
而不是 -
中使用了不正确的范围字符)。现在更新了一个稍微更有用且实际有效的示例:
using System.Text.RegularExpressions;
string[] strings = {"ABCDEFGabcdefg", "abcdefg", "ABCDEFG"};
Array.ForEach(strings, s => {
switch (s)
{
case var someVal when new Regex(@"^[a-z]+$").IsMatch(someVal):
Console.WriteLine($"{someVal}: all lower");
break;
case var someVal when new Regex(@"^[A-Z]+$").IsMatch(someVal):
Console.WriteLine($"{someVal}: all upper");
break;
default:
Console.WriteLine($"{s}: not all upper or lower");
break;
}
});
输出:
ABCDEFGabcdefg: not all upper or lower
abcdefg: all lower
ABCDEFG: all upper
使用 _ 作为丢弃对 David 的出色答案进行了小小的改进。 只是一个非常简单的字符串值作为示例。
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string userName = "Fred";
int something = 0;
switch (true)
{
case bool _ when Regex.IsMatch(userName, @"Joe"):
something = 1;
break;
case bool _ when Regex.IsMatch(userName, @"Fred"):
something = 2;
break;
default:
break;
}
Console.WriteLine(something.ToString());
}
}
从 C# 8.0 开始,答案现在是肯定的!...有点。
在 8.0 中,引入了 switch 表达式。您可以使用它来匹配许多不同风格的图案,如下所示。
string myValueBeingTested = "asdf";
string theResultValue = myValueBeingTested switch
{
var x when
Regex.IsMatch(x, "[a..z]+") => "everything is lowercase",
var y when
Regex.IsMatch(y, "[A..Z]+") => "EVERYTHING IS UPPERCASE",
"Something Specific" => "The Specific One",
_ => "The default, no match scenario"
};
它是如何工作的:switch 表达式需要一个可以将结果输入到其中的变量。上面的示例使用
theResultValue
变量来实现这一点。接下来,您将上面的 myValueBeingTested
表示的称为 范围表达式 传递到 switch中。熟悉的 case 构造被替换为 pattern expression,后跟
=>
标记,并一起称为 expressionn arm。 arm 标记右侧的任何内容都将最终出现在结果变量中。
通常,switch 表达式 要求模式是编译时常量,并且您不能在 switch 表达式 内执行任意代码。但是,我们可以通过使用 when
子句来使用
case gaurd模式来利用 Regex,如上所示。每个案例都需要连接在不同的arm中,并具有不同的一次性变量(上面的
x
和y
)。
上面显示的第三个arm是一个编译时常量字符串,用于根据需要匹配某些特定文本。上面显示的第四个 arm 使用
_
模式,这是一种类似于旧的 default:
关键字的通配符。您还可以使用 null
代替或补充 _
来单独处理 null 情况。
在我的 .NET Fiddle 示例中尝试一下。
你应该能够做这样的事情:
using System.Text.RegularExpressions;
private void fauxSwitch(string caseSwitch)
{
if(Regex.Match(caseSwitch, @"[a..z]+").Success)
{
//do something
return;
}
if(Regex.Match(caseSwitch, @"[A..Z]+").Success)
{
//do something
return;
}
/*default*/
//do something
}
尽管如此,C#7 中的模式匹配可能是更好的选择。
不。在 C#(7 之前)中,switch 语句仅接受常量值。
按照您的建议使用更复杂的表达式是函数式编程世界中称为“模式匹配”的功能。
模式匹配包含在 C#7 中
从 C# 11 开始,这变得更容易:
// named capture groups improve readability
var pattern = new Regex(@"(?<LowerCase>[a-z]+)|(?<UpperCase>[A-Z]+)");
switch(stringValue)
{
case { Success: true, Groups: [_, { Name: "LowerCase", Success: true }, _] }:
// do something
break;
case { Success: true, Groups: [_, _, { Name: "UpperCase", Success: true }] }:
// do something
break;
default:
// do something
break;
}