27

Here is a snippet of my code:

var link = socials.Where(p => p.type == Facebook).FirstOrDefault().URL;

the problem is that there aren't any social object in the list, FirstOrDefault() return null, and .URL trigger an exception.

How can I avoid this in "one" line with LINQ? Thus, if null return empty "" (or custom even better) string, else .URL?

markzzz
  • 47,390
  • 120
  • 299
  • 507

3 Answers3

48

You can use DefaultIfEmpty with an argument to specify the fallback value:

var link = socials
    .Where(p => p.type == Facebook)
    .Select(p => p.Url)
    .DefaultIfEmpty("")
    .First();

FirstOrDefault is not necessary anymore, it is safe to use First with DefaultIfEmpty.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • But DefaultIfEmpty works even if the Select return 0 object? I mean, if the where count is 0, it returns at least one ""? – markzzz Aug 21 '15 at 12:33
  • 3
    Yes, that's the sole purpose of `DefaultIfEmpty`. It comes only into play if the sequence contains no elements. Then it uses the default value of the type or - if you use the overload as in my answer - it uses the value provided. So with the same result as if the sequence contained only one element with that value. – Tim Schmelter Aug 21 '15 at 12:37
  • Saved few additional lines of code and time. Works as expected – Sagar Khatri Apr 10 '19 at 08:58
17

Another option is to use null coalesce operator

var link = (socials
    .Where(p => p.type == Facebook)
    .Select(p => p.Url)
    .FirstOrDefault()) ?? string.empty;

I understood that string.empty is preferred over "" but that may not be the case - see comment below.

UPDATE In C# 6 there is a null conditional operator (also known as the "Elvis" operator):

var link = socials
    .Where(p => p.type == Facebook)
    .Select(p => p.Url)
    .FirstOrDefault()?.URL ?? string.empty;

A simple example:

stringbuilder sb = null;
// do work
string s = sb?.ToString() ?? "no values found"; 
Peter Smith
  • 5,528
  • 8
  • 51
  • 77
  • 5
    Why is `string.empty` preferred over `""`? Tha's just a matter of personal preferences. Imo `""` is very clear. – Tim Schmelter Aug 21 '15 at 10:40
  • 2
    There's a subtle difference between yours and mine answer. You get `String.Empty` if there is no `type==facebook` and also if the first matching `Url` is `null`. [My approach](http://stackoverflow.com/a/32138070/284240) still yields `null` in that case. – Tim Schmelter Aug 21 '15 at 10:44
  • http://stackoverflow.com/questions/263191/in-c-should-i-use-string-empty-or-string-empty-or – Steve Aug 21 '15 at 10:45
6

Using C# 6 you can use a null-conditional operator (?.) to return the URL if the object returned from the LINQ statement isn't null, i.e. if a value was found, or null otherwsie.

var link = socials.Where(p => p.type == Facebook).FirstOrDefault()?.URL;

If you then want to change a null value to an empty string or a custom string then use the null-coalescing operator (??).

var link = socials.Where(p => p.type == Facebook).FirstOrDefault()?.URL ?? "No URL";

It should be noted that this won't make any distinction between whether an object wasn't found or an object was found but had a null URL value.

kjbartel
  • 10,381
  • 7
  • 45
  • 66