FirstOrDefault() result of a struct collection?

c#-4.0, linq, struct

Solution

If your collection is empty, `FirstOrDefault` will return `default(OptionalExtras)`. The default value of a struct is the struct with all its values in turn default initialized (i.e. zero, null, etc.).

If you assume that there will be an element and your code doesn't work with an empty collection, Use `First()` instead, since that will throw an exception when your collection is empty. It's generally better to fail fast than to return wrong data.

If you cannot assume that there will be an element, but also cannot deal with struct default initialization, you might make the structs in the collection a nullable value type, for example as follows:

OptionalExtras
    .Where(w => w.Code == optExtra.Code)
    .Cast<OptionalExtra?>()
    .FirstOrDefault();

This way you can get a null return even for a struct. The key idea here is to extend the set of possible values to include something other than an `OptionalExtra` to allow detection of an empty list. If you don't like nullables, you could instead use a `Maybe<>` implementation (not a .NET builtin), or use an empty-or-singleton list (e.g. `.Take(1).ToArray()`. However, a nullable struct is likely your best bet.

TL;DR;

- `.FirstOrDefault<T>()` returns `default(T)` if the sequence is empty

- Use `.First()` instead if you assume the list is non-empty.

- Cast to nullable and then use `.FirstOrDefault<T>()` when you cannot assume the list is non-empty.

Problem

So I've got a collection of `struct`s (it's actually a WCF datacontract but I'm presuming this has no bearing here). ``` List<OptionalExtra> OptionalExtras; ``` `OptionalExtra` is a `struct`. ``` public partial struct OptionalExtra ``` Now I'm running the below statement: ``` OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault(); if (multiOptExtra != null) { } ``` Now this won't compile: the operator != cannot be applied to opperands of type OptionalExtra and `'<null>'` After a little googling I realised it's because `OptionalExtra` is a `struct`. Which I believe is not nullable unless defined as a nullable type? So my question is, if my `where` statement returns no results what will be the outcome of the `FirstOrDefault` call? Will it thrown an exception? Incidently this should never happen but better safe than sorry.

Original source

Related problems