Simon
Simon

Reputation: 9425

LINQ - FirstOrDefault() then Select()

I have the following LINQ query that fires an exception when the FirstOrDefault() returns null. Ideally I would like to avoid the null check. Is there a way to do this? I wish to return 0 if there are no CPOffsets that satisfy the FirstOrDefault() call.

double offset = OrderedOffsets.FirstOrDefault(o => o.OffsetDateTime > cpTime).CPOffset;

The only way I can see to achieve this is the following:

CPOffset cpOffset = OrderedOffsets.FirstOrDefault(o => o.OffsetDateTime > cpTime);
double offset = cpOffset != null ? cpOffset.CPOffset : 0;

Is there another more succinct way? Using Select() after the FirstOrDefault() doesn't compile but I thought might be appropriate here?

Upvotes: 43

Views: 93189

Answers (3)

Romain
Romain

Reputation: 810

I think a good pattern could be :

double offset = (OrderedOffsets.FirstOrDefault(o => o.OffsetDateTime > cpTime) ?? someDefaultObject).CPOffset;

with someDefaultObject an object holding default values... With this pattern, you can change easily you default values through your code !

If OrderedOffsets can be a struct you could also just put your default value there ! :)

Upvotes: 6

Servy
Servy

Reputation: 203823

DefaultIfEmpty can be used to ensure that the collection always has at least one element.

double offset = OrderedOffsets.Where(o => o.OffsetDateTime > cpTime)
    .Select(o => o.CPOffset)
    .DefaultIfEmpty()
    .First();

Upvotes: 15

NSGaga
NSGaga

Reputation: 14302

I think this should work, I'm not near by VS to check it out...

OrderedOffsets.Where(o => o.OffsetDateTime > cpTime).Select(x => x.CPOffset).FirstOrDefault();

Upvotes: 73

Related Questions