我最近一直在关注F#,虽然我不太可能在短期内跳过篱笆,但它肯定突出了一些C#(或图书馆支持)可以让生活更轻松的领域。
特别是,我在考虑F#的模式匹配功能,它允许非常丰富的语法-比当前的开关/条件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是一个函数<车辆,int>。
[注意-这里的Switch/Case可能是错误的术语…但它表明了这个想法]
大量
并允许简单扩展(直接或通过扩展方法)到更具体的匹配,例如与VB Select…Case“x到y”用法类似的InRange(…)匹配。
另外请注意,我一直在使用上述3种变体:
-
a Func<t来源,TValue>评估版本-可与复合三元条件语句进行比较
-
-
表达式<Func<t来源,TValue>&燃气轮机;版本-作为第一个,但可由任意LINQ提供程序使用
此外,使用基于条件的表达式调用,而不是使用基于条件的表达式重新写入到一个复合表达式树中。我最近没有检查,但在一些早期的实体框架构建中,我似乎记得这是必要的,因为它不太喜欢调用表达式。它还允许更有效地使用LINQ to对象,因为它避免了重复的委托调用-测试显示了类似于上述(使用表达式形式)的匹配,与等效的C#复合条件语句相比,它以相同的速度[事实上稍微快一点]执行。为完整起见,函数<&燃气轮机;基于C#conditional语句的版本花费的时间是C#conditional语句的4倍,但仍然非常快,在大多数用例中不太可能成为主要瓶颈。