DefaultIfEmpty
DefaultIfEmpty is used to return a Default Element if the Sequence contains no elements. This Element can be the Default of the Type or a user defined instance of that Type. Example:
var chars = new List<string>() { "a", "b", "c", "d" }; chars.DefaultIfEmpty("N/A").FirstOrDefault(); // returns "a"; chars.Where(str => str.Length > 1) .DefaultIfEmpty("N/A").FirstOrDefault(); // return "N/A" chars.Where(str => str.Length > 1) .DefaultIfEmpty().First(); // returns null;
Usage in Left Joins:
With DefaultIfEmpty
the traditional Linq Join can return a default object if no match was found. Thus acting as a SQL’s Left Join. Example:
var leftSequence = new List<int>() { 99, 100, 5, 20, 102, 105 }; var rightSequence = new List<char>() { 'a', 'b', 'c', 'i', 'd' }; var numbersAsChars = from l in leftSequence join r in rightSequence on l equals (int)r into leftJoin from result in leftJoin.DefaultIfEmpty('?') select new { Number = l, Character = result }; foreach(var item in numbersAsChars) { Console.WriteLine("Num = {0} ** Char = {1}", item.Number, item.Character); }
ouput:
Num = 99 Char = c Num = 100 Char = d Num = 5 Char = ? Num = 20 Char = ? Num = 102 Char = ? Num = 105 Char = i
In the case where a DefaultIfEmpty
is used (without specifying a default value) and that will result will no matching items on the right sequence one must make sure that the object is not null
before accessing its properties. Otherwise it will result in a NullReferenceException
. Example:
var leftSequence = new List<int> { 1, 2, 5 }; var rightSequence = new List<dynamic>() { new { Value = 1 }, new { Value = 2 }, new { Value = 3 }, new { Value = 4 }, }; var numbersAsChars = (from l in leftSequence join r in rightSequence on l equals r.Value into leftJoin from result in leftJoin.DefaultIfEmpty() select new { Left = l, // 5 will not have a matching object in the right so result // will be equal to null. // To avoid an error use: // - C# 6.0 or above - ?. // - Under - result == null ? 0 : result.Value Right = result?.Value }).ToList();
DefaultIfEmpty
Table Of Contents
2
Literals
18
Regex
19
DateTime
20
Arrays
22
Enum
23
Tuples
25
GUID
26
BigInteger
28
Looping
29
Iterators
30
IEnumerable
35
Dynamic type
37
Casting
41
Interfaces
47
Methods
52
Keywords
53
Recursion
57
Inheritance
58
Generics
62
Reflection
65
LINQ Queries
66
LINQ to XML
68
XmlDocument
69
XDocument
79
Diagnostics
80
Overflow
86
Properties
89
Events
93
Structs
94
Attributes
95
Delegates
97
Networking
102
Action Filters
103
Polymorphism
104
Immutability
105
Indexer
107
Stream
108
Timers
109
Stopwatches
110
Threading
112
Async Await
114
BackgroundWorker
117
Lock Statement
118
Yield Keyword
121
Func delegates
124
ICloneable
125
IComparable
127
Using SQLite
128
Caching
129
Code Contracts
136
Pointers
144
Hash Functions
146
Cryptography
148
C# Script
149
Runtime Compile
150
Interoperability
156
Contributors