tags:

views:

106

answers:

5

As far as I can understand, the linq method FirstOrDefault() returns null if a record-set is empty. Why can't use the ?? operator against the function? Like so:

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


Update

I don't want to check if d is null later on in my code. And doing:

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

... or:

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

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

... seems a bit overkill--I'd like to do this null-check in one line of code.

+8  A: 

Because the null-coalescing operator (??) applies only to nullable reference types while Double is a value type. You could use a nullable double instead (double?).

Darin Dimitrov
And even it did work "?? 0.0" is redundant in this case.
FuleSnabel
@FuleSnabel, absolutely, as `0.0` is the default value of a double anyway.
Darin Dimitrov
+1  A: 

Making it nullable should work. But, then your making it nullable, all depends on your scenario...

Double d = new Double?[] { }.FirstOrDefault() ?? 0.0;
Alexander
+7  A: 

Actually, FirstOrDefault<T>() returns T, which is either a value or default(T).

default(T) is either null or (T)0 for value types (like double)

James Curran
+3  A: 

The method is called FirstOrDefault not FirstOrNull, i.e. it will return 0, the default value of a double anyway so there isn't a need for the ??.

Ben Robinson
Would have accepted your answer. But James Curran provided a more elaborate one. Thanks Ben.
roosteronacid
A: 

Although others have answered why you have compilation problems here, you are right that this is problematic for value types. To my knowledge, there is no way of knowing in this case whether a result of zero was because the first item really was zero, or because the IEnumerable<double>was empty.

In the example you have given, the fallback value is zero anyway, so all you need is:

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

Assuming you had a non-zero fallback value, you have a few options:

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

or

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

If you have Zen Linq Extensions, you can do:

var r = myDoubles.FirstOrFallback(fallback);
Ani