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();

.NET 小提琴現場演示

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();

.NET 小提琴現場演示

持續()

  • 返回序列的最後一個元素,或與提供的 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();

建議

  • 雖然你可以使用 FirstOrDefaultLastOrDefaultSingleOrDefault 來檢查序列是否包含任何專案,但 AnyCount 更可靠。這是因為來自這三種方法之一的 default(T) 的返回值不能證明序列是空的,因為序列的第一個/最後一個/單個元素的值同樣可以是 default(T)

  • 確定哪種方法最符合你的程式碼目的。例如,僅當你必須確保集合中的單個專案與你的謂詞匹配時才使用 Single - 否則請使用 First; 如果序列有多個匹配元素,則 Single 會丟擲異常。這當然也適用於“* OrDefault”-counterparts。

  • 關於效率:儘管確保通過查詢返回的專案(Single)或者只有一個或零(SingleOrDefault)專案通常是合適的,但這兩種方法都需要更多,通常是整個集合進行檢查以確保查詢沒有第二個匹配。這與例如 First 方法的行為不同,該方法在找到第一個匹配後可以得到滿足。