DefaultIfEmpty
如果 Sequence 不包含任何元素,則 DefaultIfEmpty 用於返回預設元素。此元素可以是型別的預設值或該型別的使用者定義例項。例:
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;
左連線中的用法 :
使用 DefaultIfEmpty
,如果找不到匹配項,傳統的 Linq Join 可以返回預設物件。因此充當 SQL 的左連線。例:
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
在使用 DefaultIfEmpty
(沒有指定預設值)並且將導致右序列上沒有匹配項的情況下,必須確保在訪問其屬性之前物件不是 null
。否則會產生一個 NullReferenceException
。例:
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();