C# 8 开关表达式
Posted
技术标签:
【中文标题】C# 8 开关表达式【英文标题】:C# 8 Switch Expression 【发布时间】:2020-12-16 14:29:59 【问题描述】:我可以用 C#8 switch expression
替换此代码片段吗?
请注意,如果 ObjectType 是 Computer,ObjectClass 将包含“person”,因此排序很重要。
另外,这个问题是学术性的,我只对switch expression
感兴趣,而不是如何解决这个特定问题。
public List<string> ObjectClass get; set;
public ObjectType ObjectType
get
if (ObjectClass.Contains("group")) return ObjectType.Group;
if (ObjectClass.Contains("computer")) return ObjectType.Computer;
if (ObjectClass.Contains("person")) return ObjectType.User;
return ObjectType.Unknown;
【问题讨论】:
这是一个开关 表达式 - 语句不返回任何内容,只有表达式返回。是的,你可以,但它不会更漂亮。您发布的操作也会多次搜索该列表,因此您应该寻找避免多次迭代的方法。您可能需要一个 LINQ 调用来返回这三个单词中的任何一个单词的第一次出现并将其映射到目标值。这只会导致一次迭代,使代码速度提高 300%ObjectType
是枚举吗?在这种情况下,您可以使用Enum.Parse<ObjectType>()
将找到的任何数据直接解析为ObjectType
正如@PanagiotisKanavos 所指出的,使用switch expression
会导致代码不美观。这是演示如何使用 switch expression
: dotnetfiddle.net/W57TEO 重写你的 getter。在我看来,在这种情况下使用 switch expression
不是一个好方法,因为 1) 没有执行匹配的值; 2) 每个case branch
不包含匹配值。
@IliarTurdushev 谢谢。问题是学术性的。我早些时候阅读了有关新开关的信息,并想看看我是否可以让它在这里工作。如果您想转发,我会将其标记为答案。
the question is academic and I am only interested in the switch expression
那是一个非常糟糕的例子。这是不使用switch表达式或switch语句更清晰的情况之一
【参考方案1】:
您可以将 LINQ 和 switch
结合使用以获得(半)高效版本:
public ObjectType type
get => ObjectClass.Select(c => c switch "group" => ObjectType.Group, "computer" => ObjectType.Computer, "person" => ObjectType.Person, _ => (ObjectType?)null)
.FirstOrDefault(t => t != null) ?? ObjectType.Unknown;
【讨论】:
没有理由切换,同样可以使用不区分大小写的Enum.TryParse
@PanagiotisKanavos 没错,但这个问题是专门关于使用 C# 8.0 switch
表达式的。
这根本没有必要,这个答案证明了这一点。这个例子根本不好。顺便说一句,if
语句的排序方式,group
优先于 computer
等。FirstOrDefault
还不够,您还需要订购它们。如果值来自枚举,这可以像OrderBy(x=>x)
一样简单
@PanagiotisKanavos 它们是这样排序的,因为在 AD 中,所有 computer
帐户也是 person
帐户(因此,.Net 查询中存在一个错误,例如子类)所以你必须首先检查computer
。【参考方案2】:
这个答案建立在@IliarTurdushev 提供的解决方案之上,应该归功于他。还根据@NetMage 的建议进行了重构,谢谢。
public class Program
public List<string> ObjectClass get; set;
public ObjectType sample
get => ObjectClass switch
_ when ObjectClass.Contains("group") => ObjectType.Group,
_ when ObjectClass.Contains("computer") => ObjectType.Computer,
_ when ObjectClass.Contains("person") => ObjectType.Person,
_ => ObjectType.Unknown;
public enum ObjectType
Group = 1,
Computer = 2,
Person = 3,
Unknown = 4
【讨论】:
这并不比原始代码好 - 它扫描列表 3 次 但回答了 Bob 提出的问题。请注意他说,“另外,这个问题是学术性的,我只对 switch 表达式感兴趣,而不是如何解决这个特定问题。” 这里的答案是“不要那样做”。这实际上被 F# 的人用作 反例 来展示 C# 的模式匹配是多么有限 那么欢迎您对原始问题投反对票。谢谢,祝您有美好的一天! 我建议使用get => ObjectClass switch
... 而不是一个完整的正文——这就是使用表达式的意义。以上是关于C# 8 开关表达式的主要内容,如果未能解决你的问题,请参考以下文章