Je vois souvent des gens utiliser Where.FirstOrDefault()
pour faire une recherche et saisir le premier élément. Pourquoi ne pas simplement utiliser Find()
? Y a-t-il un avantage à l'autre? Je ne pouvais pas faire de différence.
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
KingOfHypocrites
la source
la source
list.FirstOrDefault(x => x == "item3");
est plus concis que d'utiliser à la fois.Where
et.FirstOrDefault
.Find
est antérieur à LINQ. (il était disponible en .NET 2.0 et vous ne pouviez pas utiliser lambdas. Vous étiez obligé d'utiliser des méthodes normales ou anonymes)Réponses:
Où est la
Find
méthodeIEnumerable<T>
? (Question rhétorique.)Les
Where
etFirstOrDefault
méthodes sont applicables contre plusieurs types de séquences, y comprisList<T>
,T[]
,Collection<T>
, etc. Toute séquence qui met en œuvreIEnumerable<T>
peuvent utiliser ces méthodes.Find
est disponible uniquement pour leList<T>
. Des méthodes généralement plus applicables, sont alors plus réutilisables et ont un impact plus important.Find
surList<T>
est antérieur aux autres méthodes.List<T>
a été ajouté avec des génériques dans .NET 2.0, etFind
faisait partie de l'API de cette classe.Where
etFirstOrDefault
ont été ajoutés comme méthodes d'extension pourIEnumerable<T>
avec Linq, qui est une version ultérieure de .NET. Je ne peux pas dire avec certitude que si Linq existait avec la version 2.0, celaFind
n'aurait jamais été ajouté, mais c'est sans doute le cas pour de nombreuses autres fonctionnalités fournies dans les versions antérieures de .NET qui ont été rendues obsolètes ou redondantes par les versions ultérieures.la source
Where(condition).FirstOrDefault()
optimise au moins aussi bien et parfois mieux queFirstOrDefault(condition)
seul. Nous utilisons toujoursWhere()
pour obtenir des performances améliorées lorsqu'elles sont disponibles.Je viens de le découvrir aujourd'hui, en faisant des tests sur une liste d'objets 80K et j'ai trouvé que cela
Find()
peut être jusqu'à 1000% plus rapide que d'utiliser unWhere
avecFirstOrDefault()
. Je ne savais pas cela avant de tester une minuterie avant et après tout. Parfois c'était le même moment, sinon c'était plus rapide.la source
.ToList()
ou.ToArray()
pour exécuter réellement la requête.Find
utilise les clés primaires (donc les index), alors queWhere
c'est une simple requête SQLIl y a une différence très importante si la source des données est Entity Framework:
Find
trouvera les entités dans l'état «ajouté» qui ne sont pas encore persistantes, maisWhere
ne le seront pas. C'est par conception.la source
Find
n'est implémenté que dansList<T>
, alors qu'ilWhere().FirstOrDefault()
fonctionne avec tousIEnumerable<T>
.la source
en plus d'Anthony, répondez à la
Where()
visite de tous les enregistrements, puis retournez le (s) résultat (s) sansFind()
avoir besoin de parcourir tous les enregistrements si le prédicat correspond au prédicat donné.alors disons que vous avez List of Test class
id
et desname
propriétés.Donnera la sortie de
2
, et seulement 2 visites Find nécessaire pour donner le résultat, mais si vous utilisez,Where().FirstOrDefault()
nous visiterons tous les enregistrements et nous obtiendrons des résultats.Ainsi, lorsque vous savez que vous ne voulez que le premier résultat des enregistrements de la collection, ce
Find()
sera plus approprié alorsWhere().FirtorDefault();
la source
FirstOrDefault
va «remonter» la chaîne et arrêter de tout énumérer. J'utilise le terme «bulle» par manque d'une meilleure expression, car en fait, chaque sélecteur / prédicat sera transmis au suivant, donc la dernière méthode de la chaîne fait en fait le travail en premier.Wow, je viens de regarder le tutoriel EF de MicrosofToolbox aujourd'hui sur Youtube. Il a dit à propos de l'utilisation de Find () et FirstOrDefault (condition) dans la requête et Find () recherchera les données que vous avez effectuées sur cet objet (ajouter, modifier ou supprimer - mais pas encore enregistrées dans la base de données), tandis que FirstOrDefault ne le fera que cherchez ce qui a déjà été sauvegardé
la source
Find()
est l'équivalent IEnumerable de aFirstOrDefault()
. Vous ne devez pas enchaîner les deux .Where () avec,.FirstOrDefault()
car le.Where()
parcourt tout le tableau puis parcourra cette liste pour trouver le premier élément. Vous gagnez un temps incroyable en mettant votre prédicat de recherche dans leFirstOrDefault()
méthode.De plus, je vous encourage à lire la question liée à ce fil pour en savoir plus sur les meilleures performances d'utilisation de
.Find()
dans des scénarios spécifiques Performance de Find () vs FirstOrDefault ()la source