Costumo ver pessoas usando Where.FirstOrDefault()
para fazer uma pesquisa e pegar o primeiro elemento. Por que não usar apenas Find()
? Existe uma vantagem para o outro? Eu não sabia dizer a diferença.
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
fonte
fonte
list.FirstOrDefault(x => x == "item3");
é mais conciso do que usar ambos.Where
e.FirstOrDefault
.Find
é anterior ao LINQ. (estava disponível no .NET 2.0 e você não poderia usar lambdas Você foi forçado a usar métodos normais ou métodos anônimos.)Respostas:
Onde está o
Find
métodoIEnumerable<T>
? (Questão retórica.)A
Where
eFirstOrDefault
os métodos são aplicáveis contra vários tipos de sequências, incluindoList<T>
,T[]
,Collection<T>
, etc. Qualquer sequência que implementaIEnumerable<T>
pode utilizar estes métodos.Find
está disponível apenas para oList<T>
. Métodos geralmente mais aplicáveis, são mais reutilizáveis e têm maior impacto.Find
onList<T>
antecede os outros métodos.List<T>
foi adicionado com genéricos no .NET 2.0 eFind
fazia parte da API para essa classe.Where
eFirstOrDefault
foram adicionados como métodos de extensão para oIEnumerable<T>
Linq, que é uma versão .NET posterior. Não posso dizer com certeza que, se o Linq existisse com a versão 2.0, issoFind
nunca teria sido adicionado, mas esse é sem dúvida o caso de muitos outros recursos que vieram em versões anteriores do .NET que se tornaram obsoletos ou redundantes em versões posteriores.fonte
Where(condition).FirstOrDefault()
otimiza pelo menos também e, às vezes, melhor do queFirstOrDefault(condition)
sozinho. Sempre usamosWhere()
o desempenho aprimorado quando disponível.Acabei de descobrir hoje, fazendo alguns testes em uma lista de objetos de 80K e descobri que
Find()
pode ser até 1000% mais rápido do que usar umWhere
comFirstOrDefault()
. Eu não sabia disso até testar um cronômetro antes e depois de cada um. Às vezes era a mesma hora, caso contrário, era mais rápido.fonte
.ToList()
ou.ToArray()
para realmente executar a consulta.Find
faz uso das chaves primárias (portanto, índices), enquanto queWhere
é uma consulta sql simplesHá uma diferença muito importante se a fonte dos dados for Entity Framework:
Find
encontrará entidades no estado 'adicionado' que ainda não foram persistidas, masWhere
não serão. Isso é por design.fonte
Find
só é implementado emList<T>
, enquantoWhere().FirstOrDefault()
trabalha com todosIEnumerable<T>
.fonte
além de Anthony responder à
Where()
visita através de todos os registros e, em seguida, retornar resultado (s) enquantoFind()
não precisar percorrer todos os registros, se o predicado corresponder ao predicado especificado.digamos que você tenha propriedades
id
ename
propriedades da classe List of Test .Dará saída de
2
, e apenas 2 visitas são necessárias para dar resultado, mas se você usarWhere().FirstOrDefault()
, visitaremos todos os registros e obteremos resultados.Portanto, quando você sabe que deseja apenas o primeiro resultado dos registros na coleção
Find()
, será mais adequado do queWhere().FirtorDefault();
fonte
FirstOrDefault
'borbulha' a cadeia e para de enumerar tudo. Uso o termo 'bolha' por falta de uma expressão melhor, porque na verdade todos os seletores / predicados serão passados para o próximo, portanto, o último método da cadeia está realmente trabalhando primeiro.Uau, acabei de assistir ao tutorial da EF no MicrosofToolbox hoje no Youtube. Ele disse sobre o uso de Find () e FirstOrDefault (condição) na consulta e Find () procurará os dados que você executou algo nesse objeto (adicionar ou editar ou excluir - mas ainda não salvos no banco de dados) enquanto o FirstOrDefault apenas procure o que já foi salvo
fonte
Find()
é o equivalente IEnumerable de aFirstOrDefault()
. Você não deve encadear os dois .Where ().FirstOrDefault()
porque ele.Where()
passa por toda a matriz e, em seguida, percorre a lista para encontrar o primeiro item. Você economiza uma quantidade incrível de tempo colocando seu predicado de pesquisa noFirstOrDefault()
método.Além disso, incentivo você a ler a pergunta vinculada a este tópico para saber mais sobre os melhores desempenhos no uso de
.Find()
cenários específicos. Desempenho de Find () vs. FirstOrDefault ()fonte