I want to make following statement:
var block = blocksById.FirstOrDefault(X => X.Value == tracResult.ID).Key
My question is how to deal
Since the introduction of the null conditional operators (?), it's as simple as:
var block = blocksById.FirstOrDefault(X => X.Value == tracResult.ID)?.Key;
Keep in mind that in this scenario, even if Value
is an int
, block
will be of type Nullable<int>
, and hence, can be null
.
However if what you want to assign a default value if null
is returned you can make use of null coalescing operator (??) is this way:
var block = blocksById.FirstOrDefault(X => X.Value == tracResult.ID)?.Key ?? 6;
Nevertheless, for more complex Select
statements, the following is still valid...
Split it in Where
and Select
:
var block = blocksById.Where(x => x.Value == tracResult.ID)
.Select(x => x.Key)
.FirstOrDefault();
That way you won't get a NullRefferenceException if the FirstOrDefault returns null
.
Alternative you can give it a default value like this:
var block = blocksById.Where(x => x.Value == tracResult.ID)
.Select(x => x.Key)
.FirstOrDefault() ?? somedefaultvalue;
Or as @Silvermind stated for non nullable to nullable types (int
's):
var block = blocksById.Where(x => x.Value == tracResult.ID)
.Select(x => (int?) x.Key)
.FirstOrDefault() ?? somedefaultvalue;
Update: some people seems to have doubts about this being a valid use case and argue that the check for null has to be done later on in the program.
While in a lot of circumstances this is the case, is doesn't always have to be true, or if it is, it might be more convenient this way.
Some examples:
//one liner, null check delegated (not my favorite):
return SomeCalculatedValue(collection.Where(condition).Select(selection).FirstOrDefault());
//or a mapping (shown with default value):
var result = collection.Where(condition)
.Select(c =>
{
Foo = c.Foo,
Bar = c.Bar
}).FirstOrDefault()) ?? new { Foo = "New", Bar = "Empty"};