Angenommen, ich habe eine Methode, die int als String akzeptiert und den int zurückgibt, wenn die Syntaxanalyse erfolgreich ist, oder andernfalls einen Nullwert.
%Vor%Wie kann diese Methode so umgeschrieben werden, dass sie nicht nur mit int ?, sondern auch lang ?, dezimal? und DateTime? ?
Es ist lustig, dass du es erwähnen solltest, weil ich neulich gerade mit etwas herumgespielt habe:
%Vor% Es ist ein ähnlicher Ansatz, aber denken Sie daran wie eine bessere TryParse
-Methode, die Tuple<Boolean, T?>
zurückgibt (dies erfordert .NET 4). Die erste Eigenschaft des Tupels ist ein boolescher Wert, der angibt, ob der Parsingversuch erfolgreich oder fehlgeschlagen ist, und die zweite Eigenschaft ist ein nullwertfähiger Wert für das Argument vom Typ generic, der null
ist, wenn das Parsen fehlschlägt und der Wert beim Parsen erfolgreich ist.
Es funktioniert mit Reflektion, um eine statische Parse(String)
-Methode aus dem generischen Typargument abzurufen und ruft diese Methode für die übergebene Zeichenfolge auf. Ich habe es als eine Erweiterungsmethode erstellt, um Ihnen zu erlauben, solche Dinge zu tun:
Leider funktioniert dies nicht in enums
, da sie nicht die gleiche Signatur für die Parse-Methode haben. Sie könnten diese Erweiterung nicht benutzen, um enum
zu analysieren, aber es wäre nicht schwer, dies zu hacken um einen speziellen Fall für Enums zu machen.
Eines der schönen Dinge bei diesem Ansatz ist, dass die Kosten für das Abrufen der Methode Parse
über Reflektion nur bei der ersten Verwendung anfallen, da für alle folgenden Verwendungen ein statischer Delegat erstellt wird.
Noch eine Sache - das Einzige, was bei diesem Ansatz klobig ist, ist, dass es keine Spracherweiterungen oder syntaktischen Zucker gibt, mit denen es einfach wäre, damit zu arbeiten. Was ich mit diesem Code erreichen wollte, war ein less klobiger Weg zur Verwendung der Standardmethoden TryParse
, die in der BCL existieren.
Ich persönlich finde dieses Muster eher hässlich:
%Vor% hauptsächlich, weil es im Voraus eine Variablendeklaration und die Verwendung eines Parameters out
erfordert. Mein Ansatz oben ist nicht wirklich viel besser:
Was wirklich cool wäre, wäre eine C # -Sprachenerweiterung zu sehen, die mit einem Tuple<Boolean, T?>
funktioniert, damit wir mit diesem Typ reibungslos arbeiten können, aber ich habe das Gefühl, je mehr ich darüber schreibe, dass es nicht funktioniert Das scheint wirklich machbar.
Anstelle des Fragezeichens können Sie explizit das Schlüsselwort Nullable verwenden: zum Beispiel
int?
entspricht Nullable<int>
Daher sollte der Wechsel des ursprünglichen Designs zu Nullable<T> ParseValue(string valueAsString
) der Trick sein: Mach einfach die generische Implementierung danach.
Am besten implementieren Sie eine Erweiterungsmethode, und Sie können Enumerationen sogar analysieren. Auf diese Weise erhalten Sie eine Nullable & lt; ForAnyValueType & gt; so:
%Vor%Ich sehe nicht wirklich, warum wir das Tuple in Andrews Lösung verwenden, solange wir sowieso eine Nullable zurückgeben, scheint es, als würde man das Gleiche zweimal machen. Ich änderte seine Lösung, um TryParse zu verwenden und erlaubte, entweder einen Nullable oder einen bestimmten Standardwert als Argument anzugeben.
%Vor%Diese Typen, die Sie aufgelistet haben, haben alle eine statische Methode namens TryParse. Sie sehen ähnlich aus, aber tatsächlich sind die Signaturen völlig unterschiedlich. Sie folgen einem ähnlichen 'Muster', aber das ist vom Compiler nicht erkennbar.
Sie könnten versuchen, etwas wie folgt zu tun:
%Vor% Allerdings können Sie nicht. Der Compiler hat keine Möglichkeit (zur Kompilierzeit) zu wissen, wie man den Typ 'T' in einen Int (oder einen anderen Typ) umwandelt.
Sie können das Double-Cast-Verfahren durchführen. (Danke, Dotson)
Verwendung:
%Vor%