First FirstOrDefault Last LastOrDefault Single 和 SingleOrDefault
所有六种方法都返回序列类型的单个值,并且可以使用或不使用谓词来调用。
根据与 predicate
匹配的元素数量,或者如果没有提供 predicate
,源序列中的元素数量,它们的行为如下:
第一()
- 返回序列的第一个元素,或与提供的
predicate
匹配的第一个元素。 - 如果序列不包含任何元素,则会抛出
InvalidOperationException
,并显示以下消息:Sequence not no elements
。 - 如果序列不包含与提供的
predicate
匹配的元素,则抛出InvalidOperationException
,并显示消息Sequence contains no matching element
。
例
// Returns "a":
new[] { "a" }.First();
// Returns "a":
new[] { "a", "b" }.First();
// Returns "b":
new[] { "a", "b" }.First(x => x.Equals("b"));
// Returns "ba":
new[] { "ba", "be" }.First(x => x.Contains("b"));
// Throws InvalidOperationException:
new[] { "ca", "ce" }.First(x => x.Contains("b"));
// Throws InvalidOperationException:
new string[0].First();
FirstOrDefault()
- 返回序列的第一个元素,或与提供的
predicate
匹配的第一个元素。 - 如果序列不包含元素,或者没有与提供的
predicate
匹配的元素,则使用default(T)
返回序列类型的默认值。
例
// Returns "a":
new[] { "a" }.FirstOrDefault();
// Returns "a":
new[] { "a", "b" }.FirstOrDefault();
// Returns "b":
new[] { "a", "b" }.FirstOrDefault(x => x.Equals("b"));
// Returns "ba":
new[] { "ba", "be" }.FirstOrDefault(x => x.Contains("b"));
// Returns null:
new[] { "ca", "ce" }.FirstOrDefault(x => x.Contains("b"));
// Returns null:
new string[0].FirstOrDefault();
持续()
- 返回序列的最后一个元素,或与提供的
predicate
匹配的最后一个元素。 - 如果序列不包含任何元素,则抛出
InvalidOperationException
,并显示消息Sequence contains no elements
。 - 如果序列不包含与提供的
predicate
匹配的元素,则抛出InvalidOperationException
,并显示消息Sequence contains no matching element
。
例
// Returns "a":
new[] { "a" }.Last();
// Returns "b":
new[] { "a", "b" }.Last();
// Returns "a":
new[] { "a", "b" }.Last(x => x.Equals("a"));
// Returns "be":
new[] { "ba", "be" }.Last(x => x.Contains("b"));
// Throws InvalidOperationException:
new[] { "ca", "ce" }.Last(x => x.Contains("b"));
// Throws InvalidOperationException:
new string[0].Last();
LastOrDefault()
- 返回序列的最后一个元素,或与提供的
predicate
匹配的最后一个元素。 - 如果序列不包含元素,或者没有与提供的
predicate
匹配的元素,则使用default(T)
返回序列类型的默认值。
例
// Returns "a":
new[] { "a" }.LastOrDefault();
// Returns "b":
new[] { "a", "b" }.LastOrDefault();
// Returns "a":
new[] { "a", "b" }.LastOrDefault(x => x.Equals("a"));
// Returns "be":
new[] { "ba", "be" }.LastOrDefault(x => x.Contains("b"));
// Returns null:
new[] { "ca", "ce" }.LastOrDefault(x => x.Contains("b"));
// Returns null:
new string[0].LastOrDefault();
单()
- 如果序列恰好包含一个元素,或恰好一个元素与提供的
predicate
匹配,则返回该元素。 - 如果序列不包含任何元素,或者没有与提供的
predicate
匹配的元素,则抛出InvalidOperationException
,并显示消息Sequence contains no elements
。 - 如果序列包含多个元素,或者多个元素与提供的
predicate
匹配,则会抛出InvalidOperationException
,并显示消息“Sequence 包含多个元素”。 - 注意: 为了评估序列是否只包含一个元素,最多必须枚举两个元素。
例
// Returns "a":
new[] { "a" }.Single();
// Throws InvalidOperationException because sequence contains more than one element:
new[] { "a", "b" }.Single();
// Returns "b":
new[] { "a", "b" }.Single(x => x.Equals("b"));
// Throws InvalidOperationException:
new[] { "a", "b" }.Single(x => x.Equals("c"));
// Throws InvalidOperationException:
new string[0].Single();
// Throws InvalidOperationException because sequence contains more than one element:
new[] { "a", "a" }.Single();
SingleOrDefault()
- 如果序列恰好包含一个元素,或恰好一个元素与提供的
predicate
匹配,则返回该元素。 - 如果序列不包含元素,或者没有与提供的
predicate
匹配的元素,则返回default(T)
。 - 如果序列包含多个元素,或者多个元素与提供的
predicate
匹配,则会抛出InvalidOperationException
,并显示消息“Sequence 包含多个元素”。 - 如果序列不包含与提供的
predicate
匹配的元素,则使用default(T)
返回序列类型的默认值。 - 注意: 为了评估序列是否只包含一个元素,最多必须枚举两个元素。
例
// Returns "a":
new[] { "a" }.SingleOrDefault();
// returns "a"
new[] { "a", "b" }.SingleOrDefault(x => x == "a");
// Returns null:
new[] { "a", "b" }.SingleOrDefault(x => x == "c");
// Throws InvalidOperationException:
new[] { "a", "a" }.SingleOrDefault(x => x == "a");
// Throws InvalidOperationException:
new[] { "a", "b" }.SingleOrDefault();
// Returns null:
new string[0].SingleOrDefault();
建议
-
虽然你可以使用
FirstOrDefault
,LastOrDefault
或SingleOrDefault
来检查序列是否包含任何项目,但Any
或Count
更可靠。这是因为来自这三种方法之一的default(T)
的返回值不能证明序列是空的,因为序列的第一个/最后一个/单个元素的值同样可以是default(T)
-
确定哪种方法最符合你的代码目的。例如,仅当你必须确保集合中的单个项目与你的谓词匹配时才使用
Single
- 否则请使用First
; 如果序列有多个匹配元素,则Single
会抛出异常。这当然也适用于“* OrDefault”-counterparts。 -
关于效率:尽管确保通过查询返回的项目(
Single
)或者只有一个或零(SingleOrDefault
)项目通常是合适的,但这两种方法都需要更多,通常是整个集合进行检查以确保查询没有第二个匹配。这与例如First
方法的行为不同,该方法在找到第一个匹配后可以得到满足。