私は最近F#を検討してきましたが、すぐにフェンスを飛び越えそうにありませんが、C#(またはライブラリのサポート)が生活を楽にする可能性のあるいくつかの領域をはっきりと強調しています。
特に、F#のパターンマッチング機能について考えています。これにより、非常に豊富な構文が可能になり、現在のスイッチ/条件付き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>です。
[注-ここのスイッチ/ケースはおそらく間違った用語です...しかしそれは考えを示しています]
私にとって、これは、if / elseを繰り返し使用した同等のものや、複合3項条件式(自明ではない式では非常に厄介です-大括弧)を使用した場合よりもはるかに明確です。また、多くのキャストを回避し、VB Select ... Case "x To yに相当するInRange(...)一致など、より具体的な一致への(直接または拡張メソッドによる)単純な拡張を可能にします。 " 使用法。
(言語サポートがない場合)上記のような構造から多くの利点があると人々が考えるかどうかを測定しようとしているだけですか?
さらに、私は上記の3つのバリアントで遊んでいることに注意してください。
- 評価用のFunc <TSource、TValue>バージョン-複合3項条件ステートメントに相当
- Action <TSource>バージョン-if / else if / else if / else if / elseに相当
- Expression <Func <TSource、TValue >>バージョン-最初のものとして、任意のLINQプロバイダーが使用可能
さらに、式ベースのバージョンを使用すると、式ツリーの書き換えが可能になり、呼び出しを繰り返し使用するのではなく、本質的にすべてのブランチを単一の複合条件式にインライン化します。私は最近チェックしていませんが、初期のEntity Frameworkビルドでは、InvocationExpressionがあまり好きではなかったため、これが必要であることを思い出しているようです。また、デリゲートの呼び出しの繰り返しを回避できるため、LINQ-to-Objectsを使用してより効率的に使用できます。テストでは、同等のC#と比較して同じ速度(実際にはわずかに高速)で実行される上記のような(式フォームを使用した)一致が示されます。複合条件ステートメント。完全を期すために、Func <...>ベースのバージョンはC#の条件付きステートメントの4倍の時間がかかりましたが、それでも非常に高速であり、ほとんどのユースケースで主要なボトルネックになることはほとんどありません。
私は、上記(またはより豊富なC#言語サポートの可能性についての考え、入力、批評など)を歓迎します。
switch-case
声明の代わりに使うことを思いとどまらせます。私を誤解しないでください、それはそれがある場所だと思います、そして私はおそらく実装する方法を探すでしょう。