FirstOrDefault: Default Value Other Than Null

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Home

PUBLIC

Stack Overflow

Tags
FirstOrDefault: Default value other than null Ask Question
Users

Jobs As I understand it, in Linq the method FirstOrDefault() can return a


Default value of something other than null. What I haven't worked out is
what kind of things other than null can be returned by this (and similar)
Teams method when there are no items in the query result. Is there any particular
Q&A for work way that this can be set up so that if there is no value for a particular query
some predefined value is returned as the default value?
Learn More
.net linq

edited Oct 19 '12 at 10:33


BoltClock ♦
507k 124 1141
1188

asked Oct 19 '12 at 10:25


Sachin Kainth
19.1k 59 162 253

104 Instead of YourCollection.FirstOrDefault() , you could use


YourCollection.DefaultIfEmpty(YourDefault).First() for example. – sloth
Oct 19 '12 at 10:38

2 I've been looking for something like the above comment for quite a while, it
helped immensely. This should be the accepted answer. – Brandon Jan 10 '14 at
16:28

The above comment is the best answer. – Tom Padilla May 19 '14 at 14:45

11 Answers

¿No encuentras la respuesta? Pregunta en Stack ✕


Overflow en español.

General case, not just for value types:

static class ExtensionsThatWillAppearOnEverything


{
public static T IfDefaultGiveMe<T>(this T value, T alternate)
{
if (value.Equals(default(T))) return alternate;
return value;
}
}

var result = query.FirstOrDefault().IfDefaultGiveMe(otherDefaultValue);

Again, this can't really tell if there was anything in your sequence, or if the
first value was the default.

If you care about this, you could do something like

static class ExtensionsThatWillAppearOnIEnumerables


{
public static T FirstOr<T>(this IEnumerable<T> source, T alternate)
{
foreach(T t in source)
return t;
return alternate;
}
}
and use as

var result = query.FirstOr(otherDefaultValue);

although as Mr. Steak points out this could be done just as well by
.DefaultIfEmpty(...).First() .

edited Oct 19 '12 at 10:53

answered Oct 19 '12 at 10:34


Rawling
38.9k 5 61 104

Your generic methods need <T> in their names, but more serious is that value
== default(T) doesn't work (because who knows if T can be compared for
equality?) – AakashM Oct 19 '12 at 10:54

Thanks for pointing that out, @AakashM; I've actually tried this now and I think it
should be OK (although I don't like the boxing for value types). – Rawling Oct 19
'12 at 10:57

@Rawling Use EqualityComparer<T>.Default.Equals(value, default(T)) to


avoid the boxing and avoid an exception if value is null – Lukazoid May 2 '14 at
15:08

As I understand it, in Linq the method FirstOrDefault() can return a


Default value of something other than null.

No. Or rather, it always returns the default value for the element type...
which is either a null reference, the null value of a nullable value type, or the
natural "all zeroes" value for a non-nullable value type.

Is there any particular way that this can be set up so that if there is no
value for a particular query some predefined value is returned as the
default value?

For reference types, you can just use:

var result = query.FirstOrDefault() ?? otherDefaultValue;

Of course this will also give you the "other default value" if the first value is
present, but is a null reference...

answered Oct 19 '12 at 10:30


Jon Skeet
1065k 662 7816
8355

11 Works for me better than the accepted answer! – Jocie Jan 23 '14 at 15:42

5 This answer should be accepted. – andrey.shedko Dec 7 '15 at 12:55

I know the question asks for reference type but your solution doesn't work for
when elements are value types like int . I much prefer the use of
DefaultIfEmpty :
src.Where(filter).DefaultIfEmpty(defaultValue).First() . Works for both
value type and reference type. – KFL Feb 16 at 21:41

@KFL: For non-nullable value types I'd probably use that too - but it's more long-
winded for nullable cases. – Jon Skeet Feb 16 at 21:43

Awesome control over return types when default is null .. :) – Sundara Prabu Feb
17 at 9:53
You can use DefaultIfEmpty followed by First:

T customDefault = ...;
IEnumerable<T> mySequence = ...;
mySequence.DefaultIfEmpty(customDefault).First();

answered Jun 3 '14 at 7:34


Vitamin C
481 4 2

I love the idea of DefaultIfEmpty - it works with ALL APIs that need a default to
be specified: First() , Last() , etc. As a user, you don't need to remember
which APIs allow to specify default which don't. Very elegant! – KFL Feb 16 at
21:45

From the documentation for FirstOrDefault

[Returns] default(TSource) if source is empty;

From the documentation for default(T):

the default keyword, which will return null for reference types and zero
for numeric value types. For structs, it will return each member of the
struct initialized to zero or null depending on whether they are value or
reference types. For nullable value types, default returns a
System.Nullable, which is initialized like any struct.

Therefore, the default value can be null or 0 depending on whether the type
is a reference or value type, but you cannot control the default behaviour.

answered Oct 19 '12 at 10:33


RB.
28.3k 9 66 99

Copied over from comment by @sloth

Instead of YourCollection.FirstOrDefault() , you could use


YourCollection.DefaultIfEmpty(YourDefault).First() for example.

Example:

var viewModel = new CustomerDetailsViewModel


{
MainResidenceAddressSection =
(MainResidenceAddressSection)addresses.DefaultIfEmpty(new
MainResidenceAddressSection()).FirstOrDefault( o => o is MainResidenceAddres
RiskAddressSection = addresses.DefaultIfEmpty(new
RiskAddressSection()).FirstOrDefault(o => !(o is MainResidenceAddressSection
};

answered Jan 16 '15 at 10:51


Matas Vaitkevicius
31.7k 15 155 170

1 Note that DefaultIfEmpty returns the default IF the collection is empty (has 0
items). If you use First WITH a matching expression like in your example and
that condition doesn't find any item your return value will be empty. – OriolBG Mar
10 '17 at 12:17

Actually, I use two approaches to avoid NullReferenceException when I'm


working with collections:

public class Foo


{
public string Bar{get; set;}
}
void Main()
{
var list = new List<Foo>();
//before C# 6.0
string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
//C# 6.0 or later
var barCSharp6 = list.FirstOrDefault()?.Bar;
}

For C# 6.0 or later:

Use ?. or ?[ to test if is null before perform a member access Null-


conditional Operators documentation

Example: var barCSharp6 = list.FirstOrDefault()?.Bar;

C# older version:

Use DefaultIfEmpty() to retrieve a default value if the sequence is


empty.MSDN Documentation

Example: string barCSharp5 = list.DefaultIfEmpty(new


Foo()).FirstOrDefault().Bar;

answered May 9 '17 at 19:11


Samuel Diogo
261 3 7

The null propagation operator is not allowed in expression tree lamba's. – Lars335
Oct 23 '17 at 1:20

You can also do this

Band[] objects = { new Band { Name = "Iron Maiden" } };


first = objects.Where(o => o.Name == "Slayer")
.DefaultIfEmpty(new Band { Name = "Black Sabbath" })
.FirstOrDefault(); // returns "Black Sabbath"

This uses only linq - yipee!

answered Jan 2 '15 at 20:02


BurnWithLife
320 3 11

2 The only difference between this answer and Vitamin C's answer is that this one
uses FirstOrDefault instead of First . According to msdn.microsoft.com/en-
us/library/bb340482.aspx, the recommended usage is First – Daniel Sep 9 '15
at 21:43

But - to my eye - it provides a clearer example. – Zeek Oct 10 '17 at 9:35

I just had a similar situation and was looking for a solution that allows me to
return an alternative default value without taking care of it at the caller side
every time I need it. What we usually do in case Linq does not support what
we want, is to write a new extension that takes care of it. That´s what I did.
Here is what I came up with (not tested though):

public static class EnumerableExtensions


{
public static T FirstOrDefault<T>(this IEnumerable<T> items, T defaultVa
{
foreach (var item in items)
{
return item;
}
return defaultValue;
}

public static T FirstOrDefault<T>(this IEnumerable<T> items, Func<T, boo


T defaultValue)
{
return items.Where(predicate).FirstOrDefault(defaultValue);
}
public static T LastOrDefault<T>(this IEnumerable<T> items, T defaultVal
{
return items.Reverse().FirstOrDefault(defaultValue);
}

public static T LastOrDefault<T>(this IEnumerable<T> items, Func<T, bool


T defaultValue)
{
return items.Where(predicate).LastOrDefault(defaultValue);
}
}

answered Aug 11 '17 at 7:39


harri
337 3 16

I know its been a while but Ill add to this, based on the most popular answer
but with a little extension Id like to share the below:

static class ExtensionsThatWillAppearOnIEnumerables


{
public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> pre
Func<T> alternate)
{
var thing = source.FirstOrDefault(predicate);
if (thing != null)
return thing;
return alternate();
}
}

This allows me to call it inline as such with my own example I was having
issues with:

_controlDataResolvers.FirstOr(x => x.AppliesTo(item.Key), () =>


newDefaultResolver()).GetDataAsync(conn, item.ToList())

So for me I just wanted a default resolver to be used inline, I can do my


usual check and then pass in a function so a class isn't instantiated even if
unused, its a function to execute when required instead!

answered Oct 31 at 14:22


Aaron Gibson
452 1 5 19

Instead of YourCollection.FirstOrDefault() , you could use


YourCollection.DefaultIfEmpty(YourDefault).First() for example.

edited Apr 6 '17 at 10:29


Hakam Fostok
4,984 8 36 62

answered Apr 6 '17 at 8:53


Raj.A
11 1

When you think that it was helpful, you can upvote. This is not an answer. –
jannagy02 Apr 6 '17 at 9:19

Use DefaultIfEmpty() instead of FirstOrDefault() .

edited Oct 27 '16 at 7:01


Micha Wiedenmann
9,487 11 64 102

answered Jun 16 '16 at 10:04


Abhishek Singh
29 6

You might also like