2008-10-10 12 views
98

Ich möchte die DateTime.TryParse-Methode verwenden, um den Datetime-Wert einer Zeichenfolge in eine Nullable zu erhalten. Aber wenn ich versuche dies:Wie verwende ich DateTime.TryParse mit einer Nullable <DateTime>?

DateTime? d; 
bool success = DateTime.TryParse("some date text", out (DateTime)d); 

der Compiler sagt mir

'out' Argument nicht als Variable

klassifiziert

nicht sicher, was ich hier tun müssen. Ich habe auch versucht:

out (DateTime)d.Value 

und das funktioniert auch nicht. Irgendwelche Ideen?

Antwort

104
DateTime? d=null; 
DateTime d2; 
bool success = DateTime.TryParse("some date text", out d2); 
if (success) d=d2; 

(Es könnte elegantere Lösungen sein, aber warum nicht einfach etwas tun, wie oben?)

+3

Sie haben recht, ich war auf der Suche nach mehr von einem Einzeiler, um es zu erledigen, aber ich nehme an, dass dies tun wird.Sie mag es nicht, diese temporäre Variable zu erstellen, fühlt sich unordentlich.: -/Scheint so Szenario sollte besser unterstützt werden –

+1

siehe Binary Worrier Vorschlag psuedo-inline, dass in eine Erweiterungsmethode –

+4

Warum werfen Sie eine DateTime auf eine DateTime? Sie müssen nicht rekased d 2 bevor Sie es in den Tryparse übergeben. –

127

Als Jason sagt, eine Variable des richtigen Typs und das passieren zu schaffen. Vielleicht haben Sie es in Ihre eigene Methode zum Einkapseln wollen:

public static DateTime? TryParse(string text) 
{ 
    DateTime date; 
    if (DateTime.TryParse(text, out date)) 
    { 
     return date; 
    } 
    else 
    { 
     return null; 
    } 
} 

... oder wenn Sie den Bedingungsoperator mag:

public static DateTime? TryParse(string text) 
{ 
    DateTime date; 
    return DateTime.TryParse(text, out date) ? date : (DateTime?) null; 
} 

Oder in C# 7:

public static DateTime? TryParse(string text) => 
    DateTime.TryParse(text, out var date) ? date : (DateTime?) null; 
+3

Ich sollte wahrscheinlich nicht mit The Skeet argumentieren, aber ... sollten Sie Ihre Methode Parse aufrufen, da ich erwarten würde, dass eine Methode namens TryParse der TryParse Konvention folgt und einen booleschen Wert zurückgibt. ;-) – Myster

+0

@Myster: Nun, in keinem Fall folgt es der exakten existierenden Konvention - die, die nur zum 'Parse' verwendet werden, würden erwarten, dass sie' DateTime' zurückgeben und eine Exception auslösen, richtig? Aber ja, du kannst machen, was du willst ... und in Noda Time habe ich stattdessen die relevanten Methoden 'Parse' genannt. –

+0

Das Schlüsselwort else ist nicht notwendig (in Ihrem ersten Beispiel), da der Endpunkt des if-Blocks niemals erreicht werden kann. –

19

Sie können t, weil Nullable<DateTime> ein anderer Typ als DateTime ist. Sie benötigen eine eigene Funktion zu schreiben, es zu tun,

public bool TryParse(string text, out Nullable<DateTime> nDate) 
{ 
    DateTime date; 
    bool isParsed = DateTime.TryParse(text, out date); 
    if (isParsed) 
     nDate = new Nullable<DateTime>(date); 
    else 
     nDate = new Nullable<DateTime>(); 
    return isParsed; 
} 

this helps :)

EDIT: die (offensichtlich) entfernt nicht ordnungsgemäß getestet Erweiterungsmethode, weil (wie von einigen Hingewiesen bad hoor) Erweiterungsmethoden, die versuchen, den Parameter "this" zu ändern, funktionieren nicht mit Werttypen.

P.S. Das Bad Hoor in Frage ist ein alter Freund :)

+0

Sie wollen das Datum nicht einleiten [da Sie es als Out-Parameter verwenden] OK, ich werde aufhören, wählerisch zu sein! –

+0

Haben Sie keinen Compiler für mich, aber da DateTime ein Werttyp ist, kompiliert die Erweiterungsmethode def? –

+0

Ergebnis kommt nicht zurück, wenn Sie es machen aus - [TestFixture] public class WhenExtending { [Test] public void TryParseShouldWork() { Datetime? x = null; var res = Externes.TryParse (x, "1/1/1990"); Assert.IsTrue (res) –

16

ist hier eine leicht concised Ausgabe von dem, was Jason vorgeschlagen:

DateTime? d; DateTime dt; 
d = DateTime.TryParse(DateTime.Now.ToString(), out dt)? dt : (DateTime?)null; 
1

Ich sehe nicht, warum Microsoft nicht damit umgehen ist. Eine intelligente kleine Utility-Methode damit zu umgehen (ich hatte das Problem mit int, aber mit Datetime-int ersetzen wird der gleiche Effekt sein, könnte sein .....

public static bool NullableValueTryParse(string text, out int? nInt) 
    { 
     int value; 
     if (int.TryParse(text, out value)) 
     { 
      nInt = value; 
      return true; 
     } 
     else 
     { 
      nInt = null; 
      return false; 
     } 
    } 
+0

Unnötig *** sonst ***. https://blog.codinghorror.com/flattening-arrow-code/ – Kiquenet

4

Was ist eine Erweiterungsmethode zu schaffen?

+2

Was ist dieser erste Parameter, 'dateTime', für? Es wird nie benutzt. –

+1

@mikez - so funktioniert die Methode der Erweiterung, sie wird vom Compiler verwendet, um zu wissen, dass es sich um eine Erweiterungsmethode handelt. –

+3

@MystereMan Ich weiß, was eine Erweiterungsmethode ist. Eine passendere Signatur für eine Erweiterungsmethode wäre 'DateTime? TryParse (dieser String dateString) '. Diese Implementierung ist einfach bizarr. –