2010-08-13 10 views
6

Soweit ich das verstehe, gibt die linq-Methode FirstOrDefault()null zurück, wenn ein Datensatz leer ist. Warum kann der Operator ?? nicht gegen die Funktion verwendet werden? Wie so:FirstOrDefault() kann nicht mit? Operator

Double d = new Double[]{}.FirstOrDefault() ?? 0.0; 


aktualisieren

Ich will nicht überprüfen, ob d ist null später in meinem Code. Und tun:

Double d new Double[]{}.FirstOrDefault() == null 
     ? 0.0 
     : new Double[]{}.FirstOrDefault(); 

... oder:

var r = new Double[]{}.FirstOrDefault(); 

Double d = r == null ? 0.0 : r; 

... scheint ein wenig übertrieben - Id like this null-Check Code in einer Zeile zu tun.

+0

Während Sie testen, können Sie 'new Double [] {} ersetzen. FirstOrDefault();' mit 'default (double)'. – Kobi

Antwort

10

Eigentlich FirstOrDefault<T>() kehrt T, die entweder ein Wert oder default(T) ist.

default(T) ist entweder null oder (T)0 für Werttypen (wie double)

11

Da der nullverschmelzende Operator (??) nur für nullable Referenztypen gilt, ist Double ein Werttyp. Sie können stattdessen ein Nullable Double verwenden (double?).

+6

Und sogar es hat funktioniert "?? 0.0" ist in diesem Fall überflüssig. – FuleSnabel

+1

@FuleSnabel, absolut, wie '0.0' ist der Standardwert eines Doppelgängers sowieso. –

1

Making it nullable sollte funktionieren. Aber dann nullable Ihr es machen, hängt alles von Ihrem Szenario ...

Double d = new Double?[] { }.FirstOrDefault() ?? 0.0; 
5

Die Methode wird aufgerufen, FirstOrDefault nicht FirstOrNull, dh es wird 0 zurückgeben, ist der Standardwert eines Doppel ohnehin so dass es nicht notwendig ist, für das ??.

+0

Hätte Ihre Antwort akzeptiert. Aber James Curran lieferte eine ausführlichere. Danke Ben. – roosteronacid

0

Obwohl andere die Frage beantwortet haben, warum Sie hier Kompilierungsprobleme haben, haben Sie recht, dass dies für Werttypen problematisch ist. Nach meinem Wissen gibt es in diesem Fall keine Möglichkeit zu wissen, ob ein Ergebnis von Null war, weil der erste Gegenstand wirklich Null war, oder weil der IEnumerable<double> leer war.

Im Beispiel die Sie gegeben haben, ist der Fehlerwert Null sowieso, also alles, was Sie brauchen:

var r = new double[]{...}.FirstOrDefault(); 

Angenommen, Sie einen Nicht-Null-Fehlerwert hatte, Sie haben ein paar Optionen:

var r = !myDoubles.Any() ? fallback : myDoubles.First(); 

oder

var r = myDoubles.Cast<double?>().FirstOrDefault() ?? fallback; 

Wenn Sie Zen Linq Extensions haben, können Sie tun:

var r = myDoubles.FirstOrFallback(fallback); 
Verwandte Themen