我最近一直在研究F#,虽然我不太可能很快就克服障碍,但它无疑突出了C#(或库支持)可以使生活更轻松的某些领域。
特别是,我正在考虑F#的模式匹配功能,该功能允许使用非常丰富的语法-比当前的switch / conditional C#等效项更具表现力。我不会尝试举一个直接的例子(我的F#不符合要求),但总而言之,它允许:
- 按类型匹配(对有区别的联合进行全覆盖检查)[请注意,这还会推断出绑定变量的类型,为成员提供访问权限等]
- 谓词匹配
- 以上(以及我可能不知道的其他一些情况)的组合
虽然C#最终会借用其中的一些功能很不错,但在此期间,我一直在研究可以在运行时完成的工作-例如,将某些对象组合在一起以允许以下操作相当容易:
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 <Vehicle,int>。
[注意-也许这里的Switch / Case是错误的术语...但是它表明了这个主意]
对我来说,这比使用重复的if / else或复合三元条件(对于非平凡的表达式会变得非常混乱-方括号)更加清楚。它还避免了很多转换,并允许简单扩展(直接扩展或通过扩展方法)到更具体的匹配项,例如,与VB Select ... Case相当的InRange(...)匹配项。 ”的用法。
我只是在尝试衡量人们是否认为上述结构(在没有语言支持的情况下)有很多好处?
另外请注意,我一直在使用上述3种变体:
- 用于评估的Func <TSource,TValue>版本-与复合三元条件语句相当
- 一个Action <TSource>版本-与if / else if / else if / else if / else相当
- 一个Expression <Func <TSource,TValue >>版本-作为第一个版本,但可由任意LINQ提供程序使用
此外,使用基于表达式的版本可以重写表达式树,实质上将所有分支内联到单个复合条件表达式中,而不是使用重复调用。我最近没有检查过,但是在某些早期的Entity Framework构建中,我似乎想起来这是必要的,因为它不太喜欢InvocationExpression。由于它避免了重复的委托调用,因此还可以更高效地使用LINQ-to-Objects-测试显示,与上述C#相比,上述匹配(使用Expression形式)以相同的速度(实际上要快得多)执行匹配复合条件语句。为了完整起见,基于Func <...>的版本花费的时间是C#条件语句的四倍,但仍然非常快,并且在大多数用例中不太可能成为主要瓶颈。
我欢迎上面的任何想法/输入/批评/等等(或关于更丰富的C#语言支持的可能性...这里希望;-p)。
switch-case
声明。不要误会我的意思,我认为它已经存在,并且我可能会寻找一种实现方法。