Ich bin in der Situation, in der viele meiner Klassen Container mit bekannten, aber ungeordneten Objekten unterschiedlicher Art sind, z. Ein Container kann wie folgt aussehen:
%Vor% Wenn also o
vom Typ A
ist, sollte es in der Eigenschaft A
gespeichert werden, B
in die Eigenschaft B
und so weiter.
In F # könnte die StoreIfKnown
-Methode wie folgt geschrieben sein (entschuldige die Syntaxfehler, meine F # ist nicht großartig und ziemlich rostig):
Aber in C # scheint der einzige Weg der ziemlich wortreich zu sein:
%Vor% Ich könnte es mit dem Schlüsselwort as
machen, um das Test / Cast-Muster zu vermeiden, das schneller wäre, aber noch ausführlicher ist.
Gibt es eine elegante Möglichkeit, dies in C # zu tun?
Es ist nicht so geschickt wie Brians Lösung, aber das erfordert kein neues DSL. Sie werden bemerken, dass Sie den folgenden Code wiederholen:
%Vor%Es ist einfach genug, diese Vorlage in ihre eigene Methode zu ziehen, was in etwa so aussieht:
%Vor%Wenn Sie mit Referenztypen arbeiten, können Sie die Vorteile der Typinferenz mit den folgenden Anpassungen nutzen:
%Vor%Ich habe mit einem kleinen Matchbuilder gespielt (inspiriert von Brians Antwort ), die Typprüfung, Wächterklauseln und Rückgabe eines Ergebnisses aus der ganzen Sache erlaubt. Es verwendet Typ-Inferenz, so dass Sie nur dort einen Typ angeben müssen, an dem Sie tatsächlich möchten.
Wenn also der Typ C
eine Eigenschaft IsActive
hat, die true
sein soll, sieht das etwa so aus:
Was meiner Meinung nach ziemlich gut lesbar ist, zumal es erlaubt, dass ein Prädikat gegen den abgeleiteten Typ ausgeführt wird, bevor es tatsächlich übereinstimmt, was ich brauche.
Der Code ist ziemlich lang, da er im Hintergrund eine Reihe von teilweise angegebenen Builder-Klassen benötigt, damit die Typinferenz funktionieren kann. Daher kann ich ihn hier nicht wirklich posten. Aber wenn jemand interessiert ist, lass es mich in den Kommentaren wissen und ich werde es auf meinem Blog aufkleben und hier einen Link setzen.
Bart de Smet war einmal verrückt mit Mustererkennung, beginnend hier (geht den ganzen Weg bis zu Teil 8). Wenn Sie es schaffen, diesen ganzen Inhalt zu bewältigen, sollten keine Fragen mehr zum Musterabgleich in C # übrig bleiben. Wenn ja, können sie wahrscheinlich nicht mit stackoverflow beantwortet werden:)
Ab August 2016 und Vorschau von C # 7.0, Es gibt eine begrenzte Unterstützung für den Mustervergleich . Sie können es versuchen, wenn Sie Visual Studio "15" Preview 4 .
Gemäß dem MSDN-Blog können Sie Muster an zwei Stellen verwenden:
auf der rechten Seite von sind Ausdrücke
in den case-Klauseln in switch-Anweisungen
Mögliche Muster sind:
- ist
Konstante Muster der Form c (wobei c ein konstanter Ausdruck in C # ist), die prüfen, ob die Eingabe gleich c
Geben Sie Muster der Form T x ein (wobei T ein Typ und x ein Bezeichner ist), die testen, ob die Eingabe den Typ T hat. Wenn ja, wird der Wert der Eingabe in eine neue Variable x extrahiert vom Typ T
Var-Muster der Form var x (wobei x ein Bezeichner ist), die immer übereinstimmen, und einfach den Wert der Eingabe in eine neue Variable x mit dem gleichen Typ wie die Eingabe
Ich habe Visual Studio 15 nicht installiert, daher bin ich mir nicht sicher, ob ich den Code richtig umgeschrieben habe, aber es sollte nicht weit entfernt sein:
%Vor%Tags und Links c# f# casting guard-clause