2011-12-03 13 views
19

Eventuali duplicati:
When to use .First and when to use .FirstOrDefault with LINQ?Perché utilizzare First invece di FirstOrDefault in LINQ?

Qual è il punto di utilizzare l'operatore First in LINQ, quando si potrebbe utilizzare l'operatore FirstOrDefault invece?

var q = results.First(); // Error if empty 
+2

Potrei vedere una chiusura per un duplicato, ma ... "non costruttivo"? :(Anche se, penso che la domanda potrebbe usare chiarimenti su * perché * 'Primo '(con Error-if-empty) si pensa che sia meno ideale di' FirstOrDefault'. –

risposta

17

Per rispondere direttamente alla domanda specifica (perché utilizzare First se è sempre possibile utilizzare FirstOrDefault), ci sono casi in cui non è possibile utilizzare FirstOrDefault, perché perde le informazioni! Il "valore predefinito" è probabilmente un tipo di elemento valido nell'elenco sorgente. Non è possibile distinguere tra il primo elemento dell'enumerazione come null/predefinito e non essendoci elementi nell'elenco a meno che non si utilizzi First o prima si verifichi se esistono elementi Any, che richiede la doppia enumerazione.

Ciò è particolarmente vero per valori enumerabili con valore, come ad esempio int[]. default(int) è 0, che è anche molto probabilmente un valore valido dell'array.

In generale, i due metodi rappresentano flussi logici diversi. First verrebbe usato se non ci fossero elementi "eccezionali" (un errore), che poi vogliono gestire fuori banda nell'applicazione. In questo scenario, ti "aspetti" di avere almeno un elemento. FirstOrDefault restituisce null su un set vuoto, il che significa che è necessario eseguire un'ulteriore elaborazione con il valore restituito. Questa è una logica simile ai metodi Parse rispetto a TryParse su int/double/ecc. In effetti, la tua domanda in qualche modo conduce alla domanda più generale sul perché usare sempre le eccezioni.

Poiché First genera un'eccezione, si presta a tutte le opportunità di riutilizzo del codice fornite dalle eccezioni. Ad esempio, potresti fare:

try 
{ 
    x = arr1.First(); 
    y = arr2.First(); 
    z = arr3.First(); 
} 
catch 
{ 
    throw new ArgumentException(); 
} 
8

Per forzare esplicitamente un'eccezione per ottenere sollevato contro l'esecuzione di un controllo null.

2

È la stessa discussione di Int32.Parse rispetto a Int32.TryParse. Il primo genera un'eccezione in caso di errore, il secondo restituisce false e il programma continua senza problemi ...

Problemi correlati