A menudo veo personas que usan Where.FirstOrDefault()
para hacer una búsqueda y agarrar el primer elemento. ¿Por qué no solo usar Find()
? ¿Hay alguna ventaja para el otro? No pude notar la diferencia.
namespace LinqFindVsWhere
{
class Program
{
static void Main(string[] args)
{
List<string> list = new List<string>();
list.AddRange(new string[]
{
"item1",
"item2",
"item3",
"item4"
});
string item2 = list.Find(x => x == "item2");
Console.WriteLine(item2 == null ? "not found" : "found");
string item3 = list.Where(x => x == "item3").FirstOrDefault();
Console.WriteLine(item3 == null ? "not found" : "found");
Console.ReadKey();
}
}
}
c#
linq
linq-to-objects
Rey de los hipócritas
fuente
fuente
list.FirstOrDefault(x => x == "item3");
es más conciso que usar ambos.Where
y.FirstOrDefault
.Find
es anterior a LINQ. (estaba disponible en .NET 2.0 y no podía usar lambdas. Se vio obligado a usar métodos normales o métodos anónimos)Respuestas:
¿Dónde está el
Find
métodoIEnumerable<T>
? (Pregunta retórica.)El
Where
yFirstOrDefault
métodos son aplicables contra múltiples tipos de secuencias, incluyendoList<T>
,T[]
,Collection<T>
, etc. Cualquier secuencia que implementosIEnumerable<T>
pueden utilizar estos métodos.Find
está disponible solo paraList<T>
. Los métodos que generalmente son más aplicables, son más reutilizables y tienen un mayor impacto.Find
enList<T>
anteriores a los otros métodos.List<T>
fue agregado con genéricos en .NET 2.0, yFind
fue parte de la API para esa clase.Where
yFirstOrDefault
se agregaron como métodos de extensiónIEnumerable<T>
con Linq, que es una versión posterior de .NET. No puedo decir con certeza que si Linq existiera con la versión 2.0Find
, nunca se habría agregado, pero ese podría ser el caso de muchas otras características que aparecieron en versiones anteriores de .NET que quedaron obsoletas o redundantes en versiones posteriores.fuente
Where(condition).FirstOrDefault()
optimiza al menos tan bien y, a veces, mejor queFirstOrDefault(condition)
solo. Siempre utilizamosWhere()
para obtener un rendimiento mejorado cuando está disponible.Me acabo de enterar hoy, haciendo algunas pruebas en una lista de objetos de 80K y descubrí que
Find()
puede ser hasta un 1000% más rápido que usar unWhere
conFirstOrDefault()
. No lo sabía hasta probar un temporizador antes y después de cada uno. A veces era al mismo tiempo, de lo contrario era más rápido.fuente
.ToList()
o.ToArray()
para realizar la consulta.Find
que utiliza las claves primarias (por lo tanto, los índices), mientras queWhere
es una consulta SQL simpleHay una diferencia muy importante si la fuente de los datos es Entity Framework:
Find
encontrará entidades en el estado 'agregado' que aún no persisten, peroWhere
que no lo harán. Esto es por diseño.fuente
Find
solo se implementa enList<T>
, mientrasWhere().FirstOrDefault()
funciona con todosIEnumerable<T>
.fuente
además de la respuesta de Anthony,
Where()
visite todos los registros y luego devuelva los resultados, mientras queFind()
no es necesario recorrer todos los registros si el predicado coincide con el predicado dado.Supongamos que tiene una lista de la clase de prueba que tiene
id
yname
propiedades.Dará salida de
2
, y solo se necesitan 2 visitas Buscar para dar resultado, pero si lo usaWhere().FirstOrDefault()
, visitaremos todos los registros y luego obtendremos resultados.Entonces, cuando sabes que solo quieres el primer resultado de los registros en la colección
Find()
, será más adecuado queWhere().FirtorDefault();
fuente
FirstOrDefault
'burbujeará' la cadena y dejará de enumerar todo. Utilizo el término 'burbuja' por falta de una mejor expresión, porque en realidad cada selector / predicado se pasará al siguiente, por lo que el último método de la cadena realmente está haciendo el trabajo primero.Wow, acabo de ver el tutorial de EF de MicrosofToolbox hoy en Youtube. Dijo sobre el uso de Find () y FirstOrDefault (condición) en la consulta y Find () buscará los datos que haya realizado algo en ese objeto (agregar o editar o eliminar, pero aún no se ha guardado en la base de datos), mientras que FirstOrDefault solo busca lo que ya se ha guardado
fuente
Find()
es el equivalente IEnumerable de aFirstOrDefault()
. No debe encadenar ambos .Where () con.FirstOrDefault()
porque.Where()
recorre toda la matriz y luego recorrerá esa lista para encontrar el primer elemento. Ahorras una cantidad increíble de tiempo al poner tu predicado de búsqueda en elFirstOrDefault()
método.Además, le animo a leer la pregunta vinculada a este hilo para conocer más acerca de los mejores rendimientos en el uso de los
.Find()
escenarios específicos Rendimiento de Find () vs. FirstOrDefault ()fuente