我最近一直在研究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 。
[注意-也许这里的Switch / Case是错误的术语…但是它表明了这个想法]
对我来说,这比使用重复的if / else或复合三元条件(对于非平凡的表达式会变得非常混乱-方括号)更加清楚。它还避免了 很多 转换,并允许简单地扩展(直接或通过扩展方法)到更特定的匹配项,例如,与VB Select … Case相当的InRange(…)匹配项。 ”的用法。
我只是在尝试衡量人们是否认为上述结构(在没有语言支持的情况下)有很多好处?
另外请注意,我一直在使用上述3种变体:
此外,使用基于表达式的版本可以重写表达式树,实质上是将所有分支内联到单个复合条件表达式中,而不是使用重复调用。我最近没有检查过,但是在某些早期的Entity Framework构建中,我似乎想起来这是必要的,因为它不太喜欢InvocationExpression。由于它避免了重复的委托调用,因此还可以更有效地使用LINQ- to-Objects- 测试显示,与上述C#相比,上述匹配(使用Expression形式)以相同的速度[实际上更快]进行了匹配。复合条件语句。为了完整起见,基于Func <…>的版本花费的时间是C#条件语句的4倍,但仍非常快,并且在大多数用例中不太可能成为主要瓶颈。
我欢迎上面的任何想法/输入/批评/等等(或关于更丰富的C#语言支持的可能性…这里希望;-p)。
我知道这是一个老话题,但是在c#7中,您可以执行以下操作:
switch(shape) { case Circle c: WriteLine($"circle with radius {c.Radius}"); break; case Rectangle s when (s.Length == s.Height): WriteLine($"{s.Length} x {s.Height} square"); break; case Rectangle r: WriteLine($"{r.Length} x {r.Height} rectangle"); break; default: WriteLine("<unknown shape>"); break; case null: throw new ArgumentNullException(nameof(shape)); }