Trabalhando com uma coleção, tenho duas maneiras de obter a contagem de objetos; Count
(a propriedade) e Count()
(o método). Alguém sabe quais são as principais diferenças?
Posso estar errado, mas sempre uso a Count
propriedade em quaisquer instruções condicionais porque estou presumindo que o Count()
método executa algum tipo de consulta na coleção, onde as já Count
devem ter sido atribuídas antes de eu 'obter'. Mas isso é um palpite - não sei se o desempenho será afetado se eu estiver errado.
EDIT: Por curiosidade, então, Count()
lançará uma exceção se a coleção for nula? Porque tenho quase certeza de que a Count
propriedade simplesmente retorna 0.
.
operador a algo que é nulo.Respostas:
Descompilar a fonte para o
Count()
método de extensão revela que ele testa se o objeto éICollection
(genérico ou não) e, se for, simplesmente retorna aCount
propriedade subjacente :Portanto, se seu código acessa em
Count
vez de chamarCount()
, você pode ignorar a verificação de tipo - um benefício teórico de desempenho, mas duvido que seja perceptível!// System.Linq.Enumerable public static int Count<TSource>(this IEnumerable<TSource> source) { checked { if (source == null) { throw Error.ArgumentNull("source"); } ICollection<TSource> collection = source as ICollection<TSource>; if (collection != null) { return collection.Count; } ICollection collection2 = source as ICollection; if (collection2 != null) { return collection2.Count; } int num = 0; using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { num++; } } return num; } }
fonte
Count()
não verifica aICollection
interface não genérica . Isso foi adicionado apenas no .NET 4. Ambos 3.5 e 4 verificam aICollection<T>
interface genérica .O desempenho é apenas uma razão para escolher um ou outro. Escolher
.Count()
significa que seu código será mais genérico. Tive ocasiões em que refatorei algum código que não produzia mais uma coleção, mas sim algo mais genérico como um IEnumerable, mas outro código quebrou como resultado porque dependia de.Count
e eu tive que alterá-lo para.Count()
. Se eu fizesse questão de usar em.Count()
qualquer lugar, o código provavelmente seria mais reutilizável e sustentável. Normalmente, optar por utilizar interfaces mais genéricas, se puder, é sua melhor aposta. Por mais genérico, quero dizer a interface mais simples que é implementada por mais tipos e, portanto, resultando em maior compatibilidade entre o código.Não estou dizendo que
.Count()
é melhor, estou apenas dizendo que há outras considerações que lidam mais com a reutilização do código que você está escrevendo.fonte
O
.Count()
método pode ser inteligente o suficiente ou saber sobre o tipo em questão e, se for, pode usar a.Count
propriedade subjacente .Então, novamente, pode não ser.
Eu diria que é seguro presumir que, se a coleção tem uma
.Count
propriedade própria, essa será sua melhor aposta quando se trata de desempenho.Se o
.Count()
método não souber sobre a coleção, ele a enumerará, o que será uma operação O (n).fonte
Count
propriedade poderia ser melhor, mas aCount()
criação de métodosICollection<T>.Count
está meio documentada aqui: msdn.microsoft.com/en-us/library/bb338038(v=vs.110).aspxCount()
método é um método de extensão que itera cada elemento de umIEnumerable<>
e retorna quantos elementos existem. Se a instância deIEnumerable
for realmente umList<>
, ela será otimizada para retornar aCount
propriedade em vez de iterar todos os elementos.fonte
Count()
existe como um método de extensão do LINQ -Count
é uma propriedade emList
s, objetos de coleção .NET reais.Como tal,
Count()
quase sempre será mais lento, pois enumera a coleção / objeto consultável. Em uma lista, fila, pilha, etc., useCount
. Ou para uma matriz -Length
.fonte
Versão resumida: se você tem a opção de escolher entre uma
Count
propriedade e umCount()
método, escolha sempre a propriedade.A diferença está principalmente em torno da eficiência da operação. Todas as coleções BCL que expõem uma
Count
propriedade o fazem de maneira O (1). NoCount()
entanto, o método pode custar, e frequentemente custará O (N). Existem algumas verificações para tentar chegar a O (1) para algumas implementações, mas isso não é garantido de forma alguma.fonte
Se houver uma propriedade
Count
ouLength
, você deve sempre preferir isso aoCount()
método, que geralmente itera a coleção inteira para contar o número de elementos dentro dela. As exceções seriam quando oCount()
método fosse contra uma fonte LINQ to SQL ou LINQ to Entities, por exemplo, caso em que ele executaria uma consulta de contagem na fonte de dados. Mesmo assim, se houver umaCount
propriedade, você preferiria que ela, já que provavelmente teria menos trabalho a fazer.fonte
O
Count()
método é o método LINQ que funciona em qualquerIEnumerable<>
. Você esperaria que oCount()
método iterasse em toda a coleção para encontrar a contagem, mas acredito que o código LINQ realmente tem algumas otimizações para detectar se uma propriedade Count existe e, se houver, use-a.Portanto, os dois devem fazer coisas quase idênticas. A propriedade Count é provavelmente um pouco melhor, pois não precisa haver uma verificação de tipo lá.
fonte