Ich habe mir kürzlich F # angesehen, und obwohl ich wahrscheinlich nicht bald über den Zaun springen werde, werden definitiv einige Bereiche hervorgehoben, in denen C # (oder Bibliotheksunterstützung) das Leben erleichtern könnte.
Insbesondere denke ich über die Musteranpassungsfähigkeit von F # nach, die eine sehr reichhaltige Syntax ermöglicht - viel aussagekräftiger als die aktuellen Schalter- / bedingten C # -Äquivalente. Ich werde nicht versuchen, ein direktes Beispiel zu geben (meine F # ist nicht dazu in der Lage), aber kurz gesagt, es erlaubt:
- Übereinstimmung nach Typ (mit vollständiger Überprüfung auf diskriminierte Gewerkschaften) [Beachten Sie, dass dies auch den Typ für die gebundene Variable ableitet und den Mitgliedern Zugriff gewährt usw.]
- Übereinstimmung nach Prädikat
- Kombinationen der oben genannten (und möglicherweise einige andere Szenarien, die mir nicht bekannt sind)
Während es für C # schön wäre, irgendwann etwas von diesem Reichtum auszuleihen, habe ich mir in der Zwischenzeit angesehen, was zur Laufzeit getan werden kann - zum Beispiel ist es ziemlich einfach, einige Objekte zusammenzuschlagen, um Folgendes zu ermöglichen:
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
Dabei ist getRentPrice ein Func <Vehicle, int>.
[Anmerkung - vielleicht ist Switch / Case hier die falsche Bezeichnung ... aber es zeigt die Idee]
Für mich ist dies viel klarer als das Äquivalent mit wiederholtem if / else oder einer zusammengesetzten ternären Bedingung (die für nicht triviale Ausdrücke sehr chaotisch wird - Klammern in Hülle und Fülle). Es vermeidet auch viel Casting und ermöglicht eine einfache Erweiterung (entweder direkt oder über Erweiterungsmethoden) auf spezifischere Übereinstimmungen, z. B. eine InRange-Übereinstimmung (...), die mit der VB Select ... -Fall "x bis y" vergleichbar ist " Verwendung.
Ich versuche nur zu beurteilen, ob die Leute glauben, dass Konstrukte wie die oben genannten von großem Nutzen sind (ohne Sprachunterstützung).
Beachten Sie außerdem, dass ich mit 3 Varianten der oben genannten gespielt habe:
- eine Func <TSource, TValue> -Version zur Auswertung - vergleichbar mit zusammengesetzten ternären bedingten Anweisungen
- eine Action <TSource> -Version - vergleichbar mit if / else if / else if / else if / else
- eine Expression <Func <TSource, TValue >> -Version - als erste, aber von beliebigen LINQ-Anbietern verwendbar
Darüber hinaus ermöglicht die Verwendung der Ausdrucks-basierten Version das Umschreiben des Ausdrucksbaums, wobei im Wesentlichen alle Zweige zu einem einzigen zusammengesetzten bedingten Ausdruck zusammengefasst werden, anstatt einen wiederholten Aufruf zu verwenden. Ich habe es in letzter Zeit nicht überprüft, aber in einigen frühen Entity Framework-Builds erinnere ich mich anscheinend daran, dass dies notwendig ist, da InvocationExpression nicht besonders gut gefallen hat. Es ermöglicht auch eine effizientere Verwendung mit LINQ-to-Objects, da wiederholte Delegatenaufrufe vermieden werden. Tests zeigen, dass eine Übereinstimmung wie oben (unter Verwendung des Ausdrucksformulars) mit derselben Geschwindigkeit [tatsächlich geringfügig schneller] im Vergleich zum entsprechenden C # ausgeführt wird zusammengesetzte bedingte Anweisung. Der Vollständigkeit halber dauerte die auf Func <...> basierende Version viermal so lange wie die C # -bedingte Anweisung, ist jedoch immer noch sehr schnell und in den meisten Anwendungsfällen wahrscheinlich kein großer Engpass.
Ich freue mich über alle Gedanken / Eingaben / Kritik / usw. zu den oben genannten Themen (oder zu den Möglichkeiten einer umfassenderen Unterstützung der C # -Sprache ... hier ist die Hoffnung ;-p).
switch-case
Erklärung. Versteh mich nicht falsch, ich denke, es hat seinen Platz und ich werde wahrscheinlich nach einer Möglichkeit suchen, es umzusetzen.