如果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(); // 返回null;
使用DefaultIfEmpty传统的Linq Join如果找不到匹配项,则可以返回默认对象。因此充当SQL的Left Join。例:
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使用a(不指定默认值)并且将导致在正确的序列上没有匹配项,则必须确保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 equalsr.Valueinto leftJoin from result in leftJoin.DefaultIfEmpty() select new { Left = l, // 5右边没有匹配的对象,因此结果 // 将等于null。 // 为避免错误,请使用: // -C#6.0或更高版本-?。 // -欠结果== null?0:结果值 Right = result?.Value }).ToList();