¿Cuándo usar .First y cuándo usar .FirstOrDefault con LINQ?

He buscado y no he encontrado una respuesta clara sobre cuándo querría usar .First y cuando quieras usar .FirstOrDefault con LINQ.

  • ¿Cuándo querrías usar .First? ¿Solo cuando desee detectar la excepción si no se devolvieron resultados?

    var result = List.Where(x => x == "foo").First();
    
  • Y cuando querrias usar .FirstOrDefault? ¿Cuándo siempre querría el tipo predeterminado si no hay resultado?

    var result = List.Where(x => x == "foo").FirstOrDefault();
    
  • Y para el caso, ¿qué pasa con Take?

    var result = List.Where(x => x == "foo").Take(1);
    

preguntado el 21 de junio de 09 a las 16:06

.First y .FirstOrDefault ambos toman predicados como argumentos, por lo que var result = List.Where(x => x == "foo").First(); podría reescribirse como var result = List.First(x => x == "foo"); -

No olvides considerar Single y SingleOrDefault. Odio cuando la gente usa First cuando realmente quieren decir Single ; ) -

¡Single o SingleOrDefault arrojaría una excepción si se devuelve más de un elemento! ¡Creo que FirstOrDefault es mejor en los casos más comunes! -

El punto es que cuando esperas un resultado único debes decirlo, y la excepción indica que tu lógica falló. -

También considere que usar .FirstOrDefault() siempre te da la oportunidad de lanzar una excepción más significativa. Si se lanza una excepción de secuencia y más de una .First() en un método, puede ser difícil discernir qué enunciado es el problema. -

14 Respuestas

yo usaría First() cuando sé o espero que la secuencia tenga al menos un elemento. En otras palabras, cuando es un hecho excepcional que la secuencia está vacía.

Utiliza FirstOrDefault() cuando sepa que tendrá que comprobar si había un elemento o no. En otras palabras, cuando es legal que la secuencia esté vacía. No debe confiar en el manejo de excepciones para la verificación. (Es una mala práctica y puede afectar el rendimiento).

Finalmente, la diferencia entre First() y Take(1) es que First() devuelve el elemento en sí, mientras que Take(1) devuelve una secuencia de elementos que contiene exactamente un elemento.

Respondido 25 Feb 19, 19:02

Lo único que agregaría es que si el valor predeterminado para el tipo que está seleccionando podría ser un valor válido, por ejemplo, su resultado podría ser el valor int 0, entonces manejar la excepción parece ser la mejor manera de manejar esto . - PedroBelm

Borre eso, encontré una forma mucho mejor de lograr eso, use: DefaultIfEmpty (-1) .First () - PedroBelm

Take no devuelve exactamente un elemento, devuelve como máximo un elemento (si especifica 1, por supuesto). También podría devolver 0 elementos, si la secuencia está inicialmente vacía. - ESPÍRITU_1984

@RoyiNamir, sí en el contexto de la pregunta donde el parámetro a tomar es 1. También noté que en parens inmediatamente después de esa oración. - dris

Creo que sería mejor si explicaras cómo Take funcionó, luego explique cómo First() es el mismo que Take(1) - trisped

.First arrojará una excepción cuando no haya resultados. .FirstOrDefault no lo hará, simplemente devolverá nulo (tipos de referencia) o el valor predeterminado del tipo de valor. (por ejemplo, como 0 para un int.) La pregunta aquí no es cuándo desea el tipo predeterminado, sino más: ¿Está dispuesto a manejar una excepción o manejar un valor predeterminado? Dado que las excepciones deben ser excepcionales, FirstOrDefault se prefiere cuando no está seguro de obtener resultados de su consulta. Cuando, lógicamente, los datos deberían estar allí, se puede considerar el manejo de excepciones.

Skip() y Take() se utilizan normalmente al configurar la paginación en los resultados. (Como mostrar los primeros 10 resultados y los 10 siguientes en la página siguiente, etc.)

Espero que esto ayude.

respondido 21 nov., 16:15

.First() arrojará una excepción si no hay una fila para devolver, mientras que .FirstOrDefault() devolverá el valor predeterminado (NULL para todos los tipos de referencia) en su lugar.

Entonces, si está preparado y dispuesto a manejar una posible excepción, .First() está bien. Si prefiere comprobar el valor de retorno de != null de todos modos, entonces .FirstOrDefault() es tu mejor opción.

Pero supongo que también es una preferencia personal. Utilice el que tenga más sentido para usted y se adapte mejor a su estilo de codificación.

Respondido 26 Jul 19, 10:07

Primero()

  1. Devuelve el primer elemento de una secuencia.
  2. Lanza un error cuando no hay ningún elemento en el resultado o la fuente es nula.
  3. debe usarlo, si se espera más de un elemento y solo desea el primer elemento.

FirstOrDefault ()

  1. Devuelve el primer elemento de una secuencia o un valor predeterminado si no se encuentra ningún elemento.
  2. Lanza un error Solo si la fuente es nula.
  3. debe usarlo, si se espera más de un elemento y solo desea el primer elemento. También es bueno si el resultado está vacío.

Tenemos una tabla UserInfos, que tiene algunos registros como se muestra a continuación. Sobre la base de esta tabla a continuación, he creado un ejemplo ...

Tabla UserInfo

Cómo usar First ()

var result = dc.UserInfos.First(x => x.ID == 1);

Solo hay un registro donde ID == 1. Debe devolver este registro
ID: 1 Nombre: Manish Apellido: Dubey Correo electrónico: xyz@xyz.com

var result = dc.UserInfos.First(x => x.FName == "Rahul");   

Hay varios registros donde FName == "Rahul". Se debe devolver el primer registro.
ID: 7 Nombre: Rahul Apellido: Sharma Correo electrónico: xyz1@xyz.com

var result = dc.UserInfos.First(x => x.ID ==13);

No hay registro con ID == 13. Debería ocurrir un error.
InvalidOperationException: la secuencia no contiene elementos

Cómo utilizar FirstOrDefault ()

var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);

Solo hay un registro donde ID == 1. Debe devolver este registro
ID: 1 Nombre: Manish Apellido: Dubey Correo electrónico: xyz@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");

Hay varios registros donde FName == "Rahul". Se debe devolver el primer registro.
ID: 7 Nombre: Rahul Apellido: Sharma Correo electrónico: xyz1@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);

No hay registro con ID == 13. El valor de retorno es nulo

Espero que te ayude a entender cuándo usar First() or FirstOrDefault().

Respondido 26 ago 16, 13:08

En mi opinión, la afirmación "Debería producirse un error". bajo el tercer FirstOrDefault () - el ejemplo es engañoso. - jannik

En primer lugar, Take es un método completamente diferente. Devuelve un IEnumerable<T> y ni uno solo T, así que eso está fuera.

Entre First y FirstOrDefault, Deberías usar First cuando está seguro de que un elemento existe y si no existe, entonces hay un error.

Por cierto, si tu secuencia contiene default(T) elementos (p. ej. null) y debe distinguir entre estar vacío y el primer elemento null, no puedes usar FirstOrDefault.

Respondido el 21 de junio de 09 a las 20:06

Primero:

  • Devuelve el primer elemento de una secuencia.
  • Lanza una excepción: no hay elementos en el resultado
  • Usar cuando: cuando se espera más de 1 elemento y solo desea el primero

Primero o predeterminado:

  • Devuelve el primer elemento de una secuencia o un valor predeterminado si no se encuentra ningún elemento.
  • Lanza una excepción: solo si la fuente es nula
  • Usar cuando: cuando se espera más de 1 elemento y solo desea el primero. También está bien que el resultado esté vacío

De: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/

Respondido 04 Abr '13, 15:04

Otra diferencia a tener en cuenta es que si está depurando una aplicación en un entorno de producción, es posible que no tenga acceso a los números de línea, por lo que debe identificar qué .First() declaración en un método arrojó la excepción puede ser difícil.

El mensaje de excepción tampoco incluirá ninguna expresión Lambda que pueda haber utilizado, lo que haría que cualquier problema sea incluso más difícil de depurar.

Por eso siempre uso FirstOrDefault() aunque sé que una entrada nula constituiría una situación excepcional.

var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
   throw new Exception(string.Format("Can't find customer {0}.", customerId));
}

Respondido el 17 de Septiembre de 14 a las 01:09

Primero()

Cuando sepa que el resultado contiene más de 1 elemento esperado y debe solo el primer elemento de la secuencia.

FirstOrDefault ()

FirstOrDefault () es como First () excepto que, si ningún elemento coincide con la condición especificada, devuelve el valor predeterminado del tipo subyacente de colección genérica. No lanza InvalidOperationException si no se encuentra ningún elemento. Pero la colección de un elemento o una secuencia es nula y genera una excepción.

Respondido el 21 de Septiembre de 16 a las 11:09

Este tipo de función pertenece a los operadores de elementos. Algunos operadores de elementos útiles se definen a continuación.

  1. Primero / Primero o Por defecto
  2. Last / LastOrDefault
  3. Sencillo / Sencillo o Predeterminado

Usamos operadores de elementos cuando necesitamos seleccionar un solo elemento de una secuencia en función de una determinada condición. Aquí hay un ejemplo.

  List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };

El operador First () devuelve el primer elemento de una secuencia después de satisfacer la condición. Si no se encuentra ningún elemento, lanzará una excepción.

int resultado = items.Where (item => item == 2) .First ();

El operador FirstOrDefault () devuelve el primer elemento de una secuencia después de satisfacer la condición. Si no se encuentra ningún elemento, devolverá el valor predeterminado de ese tipo.

int result1 = items.Where (item => item == 2) .FirstOrDefault ();

Respondido 29 ago 18, 06:08

Encontré un sitio web que aparece para explicar la necesidad de FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
Si no hay resultados para una consulta y desea llamar a First () o Single () para obtener una sola fila ... Obtendrá una excepción "La secuencia no contiene elementos".

Descargo de responsabilidad: nunca he usado LINQ, así que mis disculpas si esto está fuera de lugar.

Respondido el 21 de junio de 09 a las 20:06

someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)

Cual usar? Debe decidirse por la lógica empresarial, y no por el temor a una excepción / falla del programa.

Por ejemplo, si la lógica empresarial dice que no podemos tener cero transacciones en ningún día hábil (solo suponga). Entonces no debería intentar manejar este escenario con alguna programación inteligente. Siempre usaré First () sobre dicha colección, y dejaré que el programa falle si algo más arruina la lógica empresarial.

Código:

var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()

Me gustaría ver los comentarios de otros sobre esto.

Respondido el 21 de junio de 09 a las 23:06

El valor predeterminado para los tipos de referencia y que aceptan valores NULL es nulo. - dsa

Fallar rápidamente es bueno; sin embargo, para el escenario que describió, prefiero ver Primero, hacer que falle, detectar la excepción y luego devolver un error significativo. Como catch (InvalidOperationException e) {throw new InvalidOperationException ("¡No se pueden tener cero transacciones en un día!", E)}; Pero sí, usar el valor predeterminado para evitar lidiar con un problema de lógica empresarial real es muy malo. - Mathieson

Ok déjame dar mis dos centavos. Primero / Primero o por defecto son para cuando usa el segundo constructor. No explicaré qué es, pero es cuando potencialmente siempre usaría uno porque no desea causar una excepción.

person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
    return string.IsNullOrEmpty(p.Relationship);
}));

Respondido el 03 de diciembre de 11 a las 22:12

No exactamente. El primer constructor se usa ampliamente cuando necesita recuperar solo un elemento o tiene que evitar un error de compilación al asignar el resultado a un valor que no es una matriz y está seguro de que la consulta devuelve exactamente un resultado. Si bien puede parecer más rápido usar el segundo constructor en lugar de usar un .Where () adicional (porque pensar LINQ deja de evaluar elementos en la lista después de encontrar el primero) siempre se detiene en el primer elemento - usr-local-ΕΨΗΕΛΩΝ

Otros han descrito muy bien la diferencia entre First() y FirstOrDefault(). Quiero dar un paso más en la interpretación de la semántica de estos métodos. En mi opinión FirstOrDefault se está usando mucho. En la mayoría de los casos, cuando está filtrando datos, esperaría obtener una colección de elementos que coincidan con la condición lógica o un solo elemento único por su identificador único, como un usuario, libro, publicación, etc. por qué podemos llegar tan lejos como para decir eso FirstOrDefault() es un olor a código no porque haya algo malo en él, sino porque se usa con demasiada frecuencia. Esta publicación de blog explora el tema en detalle. OMI la mayoría de las veces SingleOrDefault() es una alternativa mucho mejor, así que tenga cuidado con este error y asegúrese de utilizar el método más apropiado que represente claramente su contrato y expectativas.

Respondido 28 Feb 20, 16:02

Dependiendo de tu contexto .SingleOrDefault() se puede usar incorrectamente con la misma facilidad y puede afectar el rendimiento con ciertos tipos de consultas. La implementación subyacente de .SingleOrDefault() realmente usa .Take(2) luego aplica la lógica de validación. El olor del código está más en por qué usamos O por defecto () en absoluto, no necesariamente el Nombre vs Soltero Si nuestro código ya ha asumido o validado previamente que la condición solo devolverá 1 o ninguna fila, ¿debemos seguir usando y validando .Single() más adelante en la cadena de métodos? - Chris Schaller

linq hay muchas formas de implementar una consulta simple y única en colecciones, solo escribimos uniones en sql, se puede aplicar un filtro primero o último según la necesidad y la necesidad.

Aquí hay un ejemplo en el que podemos encontrar un elemento con un id en una colección. Para agregar más sobre esto, los métodos Primero, FirstOrDefault, idealmente devolvería lo mismo cuando una colección tenga al menos un registro. Sin embargo, si una colección está bien que esté vacía. luego First devolverá una excepción pero FirstOrDefault regresará null o por defecto. Por ejemplo, int devolverá 0. Por lo tanto, se dice que el uso de tales es una preferencia personal, pero es mejor usar FirstOrDefault para evitar el manejo de excepciones. aquí hay un ejemplo en el que ejecutamos una colección de lista de transacciones

contestado el 24 de mayo de 17 a las 16:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.