【发布时间】:2010-09-14 11:06:30
【问题描述】:
我最近一直在研究 F#,虽然我不太可能很快越界,但它肯定突出了 C#(或库支持)可以让生活更轻松的一些领域。
特别是,我正在考虑 F# 的模式匹配功能,它允许非常丰富的语法 - 比当前的 switch/conditional C# 等价物更具表现力。我不会直接举个例子(我的 F# 不行),但总之它允许:
- 按类型匹配(对有区别的联合进行全面覆盖检查)[请注意,这也推断绑定变量的类型,授予成员访问权限等]
- 按谓词匹配
- 上述情况的组合(可能还有一些我不知道的其他情况)
虽然 C# 最终借用 [ahem] 的一些丰富性会很可爱,但在此期间,我一直在研究可以在运行时做什么 - 例如,将一些对象拼凑在一起是相当容易的允许:
var getRentPrice = new Switch<Vehicle, int>()
.Case<Motorcycle>(bike => 100 + bike.Cylinders * 10) // "bike" here is typed as Motorcycle
.Case<Bicycle>(30) // returns a constant
.Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
.Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
.ElseThrow(); // or could use a Default(...) terminator
其中 getRentPrice 是一个 Func
[注意——这里的 Switch/Case 可能是错误的术语......但它表明了这个想法]
对我来说,这比使用重复 if/else 或复合三元条件(对于非平凡表达式变得非常混乱 - 大量括号)的等价物要清楚得多。它还避免了 lot 的强制转换,并允许简单的扩展(直接或通过扩展方法)到更具体的匹配,例如与 VB Select 相当的 InRange(...) 匹配。 ..大小写“x To y”用法。
我只是想判断人们是否认为上述结构有很多好处(在没有语言支持的情况下)?
另外请注意,我一直在玩上述的 3 个变体:
- 用于评估的 Func
版本 - 可与复合三元条件语句相媲美 - Action
版本 - 类似于 if/else if/else if/else if/else - 表达式
> 版本 - 作为第一个版本,但可供任意 LINQ 提供程序使用
此外,使用基于表达式的版本可以重写表达式树,本质上是将所有分支内联到单个复合条件表达式中,而不是使用重复调用。我最近没有检查过,但在一些早期的实体框架构建中,我似乎记得这是必要的,因为它不太喜欢 InvocationExpression。它还允许更有效地使用 LINQ-to-Objects,因为它避免了重复的委托调用 - 与等效的 C# 相比,测试显示类似上述的匹配(使用表达式表单)以相同的速度 [实际上快一点]复合条件语句。为了完整起见,基于 Func<...> 的版本所用的时间是 C# 条件语句的 4 倍,但仍然非常快,在大多数用例中不太可能成为主要瓶颈。
我欢迎任何关于上述(或更丰富的 C# 语言支持的可能性...希望 ;-p)的想法/输入/批评/等。
【问题讨论】:
-
“我只是想判断人们是否认为上述结构有很多好处(在没有语言支持的情况下)?” 恕我直言,是的。类似的东西不是已经存在了吗?如果没有,请鼓励编写一个轻量级库。
-
您可以在其选择案例语句中使用支持此功能的 VB .NET。哎呀!
-
我也会吹响自己的号角并添加一个指向我的图书馆的链接:functional-dotnet
-
我喜欢这个想法,它使 switch-case 的形式非常好、更灵活;然而,这难道不是一种使用类似 Linq 的语法作为 if-then 包装器的修饰方式吗?我会劝阻某人不要使用它来代替真正的交易,即
switch-case声明。不要误会我的意思,我认为它有它的位置,我可能会寻找一种方法来实现。 -
虽然这个问题已经有两年多了,但提到 C# 7 即将推出(ish)具有模式匹配功能的感觉是恰当的。
标签: c# switch-statement