ror*_*.ap 6 .net c# pattern-matching
如果我有一个像这样的 if 语句,我无法在正文中if (currentShape is ITable table || currentShape is AutoShape autoShape)使用tableor ,因为我收到CS0165 编译器错误。autoShape
对于带有失败的 switch 语句也是如此:
void Foo(object o)
{
switch (o)
{
case int i:
case string s:
case Guid g:
string bar = i?.ToString() ?? s?.ToString() ?? g.ToString(); // cannot use i, s, or g.
break;
}
}
Run Code Online (Sandbox Code Playgroud)
我明白为什么,但我想知道,这是模式匹配的限制,即您不能在复合if语句中使用它,或者是否有正确的方法来构造语句,以便我可以使用任一变量(例如,通过将它们初始化为null 所以我至少可以做一个空检查)?
从 C# 9 开始,您可以执行以下操作
带 switch 语句
switch (o)
{
case object probe when probe is int or string or Guid:
string bar = probe.ToString();
break;
}
Run Code Online (Sandbox Code Playgroud)
并带有 switch 表达式
var bar = o switch
{
int or string or Guid => o.ToString()
};
Run Code Online (Sandbox Code Playgroud)
如果确实有两个单独的事情需要实现,则不要组合模式表达式。两个单独的 if 语句效果会更好。
if (currentShape is ITable table)
{
// do something with tables
}
if (currentShape is AutoShape autoShape)
{
// do something with autoshapes
}
Run Code Online (Sandbox Code Playgroud)
但是,您的另一个示例说明条件之间可能存在一些共同的功能。 ToString()可能是一个坏例子,你可以这样做:
string? bar = o.ToString(); // doesn't matter the type of object
Run Code Online (Sandbox Code Playgroud)
但假设您可能希望根据类型应用不同的格式。在这种情况下,switch 表达式可能会很有用。例如:
string? bar =
o switch
{
int i => i.ToString("D3"), // three digits
Guid g => g.ToString("N"), // no hyphens
string s => s, // no need to call ToString on a string
_ => o.ToString() // all other types
};
Run Code Online (Sandbox Code Playgroud)
您还询问变量是否可以用空值初始化,以便可以进行空值检查。这对于不可空类型(例如int. 对于可为 null 的类型,它会导致无关的比较操作(首先测试类型并分配 null,其次测试 null)。保持表达式分离可确保最少的操作数。