Mit .HasValue() in LinQ-beim Umgang mit einem Nullable-Typ, ist es ein Weg, um loszuwerden, die "Möglich SystemInvalidException"?
Habe ich eine Liste von Foo's
.
Foo
hat eine CreateDate
Typ DateTime?
Möchte ich, um die älteste Foo
. Ich habe versucht mit dem intuitiven Weg, aber ich bekomme einen möglichen System.InvalidOperationException
.
DateTime oldestFoo =
(from f in allFoos where f.CreateDate.HasValue select f.CreateDate.Value).Min();
Gibt es etwas, was ich verpasst habe oder ist es einfach nicht möglich, auf diese Weise?
Kann ich es auch ohne LinQ auf diese Weise, aber ich will lernen, den anderen Ansatz zu.
DateTime oldestFoo = DateTime.MaxValue;
foreach (var foo in allFoos)
{
if (foo.CreateDate.HasValue && oldestFoo > foo.CreateDate)
{
oldestFoo = (DateTime)foo.CreateDate;
}
}
- Was wollen Sie, das Ergebnis zu werden, wenn es nicht alle Ergebnisse mit den Werten? (Eine kurze, aber komplette Programm würde hier helfen...)
- Falls nicht vorhanden, oldestFoo werden können DateTime.MaxValue.
- Mein Punkt ist: wie würden Sie erwarten, dass
Min()
wissen? - Zuerst schrieb ich die foreach-Beispiel, das perfekt funktioniert, aber ich wollte eine LinQ-version, und ich weiß einfach nicht, warum kann ich nicht verwenden
HasValue()
und.Value
wie. Hmm. So das eigentliche problem ist, dass ich nicht dieDateTime.MaxValue
in meiner LinQ-code. - Ja ich bekomme es jetzt, denke ich. Alle mein Fokus lag auf
HasValue()
undValue
🙂 - Vielen Dank für das entfernen meines tunnel-vision und mich immer wieder auf den richtigen Weg.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur im Falle, du bist immer noch stecken, möchten Sie vielleicht zu prüfen, mit
DefaultIfEmpty
- sehen, ob das hilft:Ich nicht denken, die Sie verwenden möchten
GetValueOrDefault
innerhalb Ihrer Abfrage, sonst wirst du noch habe ein problem, wenn die erste Abfrage gibt keine Ergebnisse zurück an alle.Select
. Beheben wird.f.CreateDate.Value
immer noch ein "System Möglich.InvalidOperationException". Ich denke, Resharper verstehen, "Wenn(...HasValue) ...Wert", aber nicht "Wo(...HasValue).Wählen Sie(...Wert), auch wenn es gleich aussieht für mich.Können Sie die
GetValueOrDefault
Methode, die nicht dazu führen, dass eine Ausnahme, und da es keine null-Werte an diesem Punkt, das Ergebnis ist das gleiche:select (DateTime)f.CreateDate
, weil Sie bereits dafür gesorgt hatte, dass Sie einen Wert ein, mitHasValue
?HasValue
Zustand Unkraut aus den null-Werten in einem anderen Teil des Codes.DateTime.MaxValue
größer ist als alle anderenDateTime
Wert. Es funktioniert nicht in Situationen, in denen Sie nicht umwandeln kann einen null-Wert in einen dummy-Wert, der nicht genutzt werden..Value
erhalten, können Sie eine compiler-Warnung aus, da sich die Besetzung an sich könnte möglicherweise zu einer Ausnahme führen.Oder, etwas mehr auf den Punkt:
Mein Vorschlag ist NICHT Projekt
DateTime?
zuDateTime
vor dem AufrufMin
.Hier ein
Nullable<int>
Stichprobe, die nicht Projekt zuint
um zu veranschaulichen, wie dieMin
undMax
Erweiterungen Verhalten sich die mit leeren und verschiedene Listen von nullable int.Die Ausgabe des obigen ist:
Statt der Filterung der
DateTime?
- Instanzen in der Liste der Kicker, um nur diejenigen, die Werte, ermöglichen dieMin
Erweiterung für die Arbeit mit denDateTime?
Werte statt der Projektion aufDateTime
. Bei einer leeren Liste (wie im Beispiel oben) erhalten Sie einenull
Wert vonMin
statt derInvalidOperationException
.