C# Language Innanzitutto, FirstOrDefault, Last, LastOrDefault, Single e SingleOrDefault

Esempio

Tutti e sei i metodi restituiscono un singolo valore del tipo di sequenza e possono essere chiamati con o senza un predicato.

A seconda del numero di elementi che corrispondono al predicate o, se non viene fornito alcun predicate , il numero di elementi nella sequenza sorgente, si comportano come segue:

Primo()

  • Restituisce il primo elemento di una sequenza o il primo elemento che corrisponde al predicate fornito.
  • Se la sequenza non contiene elementi, viene generata una InvalidOperationException con il messaggio: "Sequenza non contiene elementi".
  • Se la sequenza non contiene elementi corrispondenti al predicate fornito, viene generata una InvalidOperationException con il messaggio "Sequenza non contiene alcun elemento corrispondente".

Esempio

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

Live Demo su .NET Fiddle

FirstOrDefault ()

  • Restituisce il primo elemento di una sequenza o il primo elemento che corrisponde al predicate fornito.
  • Se la sequenza non contiene elementi o nessun elemento che corrisponde al predicate fornito, restituisce il valore predefinito del tipo di sequenza usando il default(T) .

Esempio

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

Live Demo su .NET Fiddle

Scorso()

  • Restituisce l'ultimo elemento di una sequenza o l'ultimo elemento che corrisponde al predicate fornito.
  • Se la sequenza non contiene elementi, viene lanciata una InvalidOperationException con il messaggio "Sequenza non contiene elementi".
  • Se la sequenza non contiene elementi corrispondenti al predicate fornito, viene generata una InvalidOperationException con il messaggio "Sequenza non contiene alcun elemento corrispondente".

Esempio

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

  • Restituisce l'ultimo elemento di una sequenza o l'ultimo elemento che corrisponde al predicate fornito.
  • Se la sequenza non contiene elementi o nessun elemento che corrisponde al predicate fornito, restituisce il valore predefinito del tipo di sequenza usando il default(T) .

Esempio

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

Singolo ()

  • Se la sequenza contiene esattamente un elemento, o esattamente un elemento che corrisponde al predicate fornito, tale elemento viene restituito.
  • Se la sequenza non contiene elementi o nessun elemento corrispondente al predicate fornito, viene generata una InvalidOperationException con il messaggio "Sequenza non contiene elementi".
  • Se la sequenza contiene più di un elemento o più di un elemento che corrisponde al predicate fornito, viene generata una InvalidOperationException con il messaggio "Sequenza contiene più di un elemento".
  • Nota: per valutare se la sequenza contiene esattamente un elemento, al massimo due elementi devono essere enumerati.

Esempio

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

  • Se la sequenza contiene esattamente un elemento, o esattamente un elemento che corrisponde al predicate fornito, tale elemento viene restituito.
  • Se la sequenza non contiene elementi o nessun elemento corrispondente al predicate fornito, viene restituito il default(T) .
  • Se la sequenza contiene più di un elemento o più di un elemento che corrisponde al predicate fornito, viene generata una InvalidOperationException con il messaggio "Sequenza contiene più di un elemento".
  • Se la sequenza non contiene elementi corrispondenti al predicate fornito, restituisce il valore predefinito del tipo di sequenza usando il default(T) .
  • Nota: per valutare se la sequenza contiene esattamente un elemento, al massimo due elementi devono essere enumerati.

Esempio

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

raccomandazioni

  • Sebbene sia possibile utilizzare FirstOrDefault , LastOrDefault o SingleOrDefault per verificare se una sequenza contiene elementi, Any o Count sono più affidabili. Questo perché un valore di ritorno di default(T) da uno di questi tre metodi non dimostra che la sequenza sia vuota, poiché il valore del primo / ultimo / singolo elemento della sequenza potrebbe essere ugualmente default(T)

  • Decidi quali metodi si adattano di più al tuo codice. Ad esempio, usa Single solo se devi assicurarti che ci sia un singolo oggetto nella collezione che corrisponde al tuo predicato, altrimenti usa First ; come Single lancia un'eccezione se la sequenza ha più di un elemento corrispondente. Questo ovviamente vale anche per le controparti "* OrDefault".

  • Riguardo all'efficienza: sebbene sia spesso opportuno assicurarsi che vi sia un solo elemento ( Single ) o, o solo uno o zero ( SingleOrDefault ), restituiti da una query, entrambi questi metodi richiedono più, e spesso l'intero, della raccolta da esaminare per assicurarsi che non ci sia una seconda corrispondenza alla domanda. Questo è diverso dal comportamento di, ad esempio, il First metodo, che può essere soddisfatto dopo aver trovato la prima corrispondenza.