我最近一直在关注 F # ,虽然我不太可能在短期内越过栅栏,但它确实突出了 C # (或库支持)可以让生活变得更轻松的一些领域。
我特别想到的是 F # 的模式匹配功能,它允许非常丰富的语法——比当前的 switch/条件 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 或复合三元条件(对于非平凡的表达式——大量的方括号)的等价物要清楚得多。它还避免了 很多的强制转换,并允许简单的扩展(直接或通过扩展方法)到更具体的匹配,例如 InRange (...)匹配类似于 VB Select... Case“ x To y”的用法。
我只是试图估计人们是否认为像上面这样的结构(在缺乏语言支持的情况下)有很多好处?
另外请注意,我一直在使用以上三种变体:
此外,使用基于 Expression 的版本可以重写 Expression-tree,实质上将所有分支内联到一个复合条件 Expression 中,而不是使用重复调用。我最近还没有检查过,但是在一些早期的实体框架构建中,我似乎记得这是必要的,因为它不太喜欢 InvocationExpression。它还允许更有效地使用 LINQ-to-Objects,因为它避免了重复的委托调用——测试显示,与等效的 C # 复合 If判断语句相比,上面的匹配(使用表达式表单)以相同的速度(实际上稍微快一点)执行。出于完整性考虑,基于 Func < ... > 的版本花费的时间是 C # If判断语句的4倍,但仍然非常快,不太可能成为大多数用例的主要瓶颈。
我欢迎任何关于上述(或者更丰富的 C # 语言支持的可能性)的想法/输入/评论/等等。