Trabajando con una colección, tengo dos formas de obtener el recuento de objetos; Count
(la propiedad) y Count()
(el método). ¿Alguien sabe cuáles son las diferencias clave?
Puede que esté equivocado, pero siempre uso la Count
propiedad en las declaraciones condicionales porque supongo que el Count()
método realiza algún tipo de consulta contra la colección, donde ya Count
debe haber sido asignado antes de que yo 'obtenga'. Pero eso es una suposición, no sé si el rendimiento se verá afectado si me equivoco.
EDITAR: Entonces, por curiosidad, ¿ Count()
lanzará una excepción si la colección es nula? Porque estoy bastante seguro de que la Count
propiedad simplemente devuelve 0.
.
operador a algo que es nulo.Respuestas:
La descompilación de la fuente para el
Count()
método de extensión revela que prueba si el objeto es unICollection
(genérico o no) y, si es así, simplemente devuelve el subyacenteCount
propiedad :Por lo tanto, si su código accede en
Count
lugar de llamarCount()
, puede omitir la verificación de tipos, un beneficio de rendimiento teórico, ¡pero dudo que sea notable!// 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; } }
fuente
Count()
no se comprueba laICollection
interfaz no genérica . Esto solo se agregó en .NET 4. Tanto 3.5 como 4 verifican laICollection<T>
interfaz genérica .El rendimiento es solo una de las razones para elegir uno u otro. Elegir
.Count()
significa que su código será más genérico. He tenido ocasiones en las que refactoricé un código que ya no producía una colección, sino algo más genérico como un IEnumerable, pero otro código se rompió como resultado porque dependía.Count
y tuve que cambiarlo a.Count()
. Si me propuse usar.Count()
todas partes, el código probablemente sería más reutilizable y fácil de mantener. Por lo general, optar por utilizar las interfaces más genéricas si puede salirse con la suya es su mejor opción. Por más genérico, me refiero a la interfaz más simple que se implementa con más tipos y, por lo tanto, le proporciona una mayor compatibilidad entre el código.No digo que
.Count()
sea mejor, solo digo que hay otras consideraciones que se ocupan más de la reutilización del código que está escribiendo.fuente
El
.Count()
método puede ser lo suficientemente inteligente, o conocer el tipo en cuestión, y si es así, podría usar el.Count
propiedad .Entonces de nuevo, tal vez no.
Yo diría que es seguro asumir que si la colección tiene una
.Count
propiedad en sí misma, esa será su mejor apuesta en lo que respecta al rendimiento.Si el
.Count()
método no conoce la colección, la enumerará, lo que será una operación O (n).fuente
Count
propiedad podría ser mejor, pero el uso deCount()
métodosICollection<T>.Count
está documentado aquí: msdn.microsoft.com/en-us/library/bb338038(v=vs.110).aspxCount()
El método es un método de extensión que itera cada elemento de unIEnumerable<>
y devuelve cuántos elementos hay. Si la instancia deIEnumerable
es en realidad aList<>
, entonces está optimizada para devolver laCount
propiedad en lugar de iterar todos los elementos.fuente
Count()
¿Existe como un método de extensión de LINQ?Count
es una propiedad enList
s, objetos de colección .NET reales.Como tal,
Count()
casi siempre será más lento, ya que enumerará la colección / objeto consultable. En una lista, cola, pila, etc., utiliceCount
. O para una matriz -Length
.fuente
Versión corta: si puede elegir entre una
Count
propiedad y unCount()
método, elija siempre la propiedad.La diferencia radica principalmente en la eficiencia de la operación. Todas las colecciones de BCL que exponen una
Count
propiedad lo hacen de forma O (1). SinCount()
embargo, el método puede costar, y con frecuencia lo hará, O (N). Hay algunas comprobaciones para intentar llevarlo a O (1) para algunas implementaciones, pero de ninguna manera está garantizado.fuente
Si hay una propiedad
Count
oLength
, siempre debe preferir eso alCount()
método, que generalmente itera toda la colección para contar el número de elementos dentro. Las excepciones serían cuando elCount()
método está en contra de una fuente LINQ to SQL o LINQ to Entities, por ejemplo, en cuyo caso realizaría una consulta de recuento contra la fuente de datos. Incluso entonces, si hay unaCount
propiedad, querrá preferirla, ya que probablemente tenga menos trabajo que hacer.fuente
El
Count()
método es el método LINQ que funciona en cualquierIEnumerable<>
. Esperarías elCount()
método itere sobre toda la colección para encontrar el recuento, pero creo que el código LINQ en realidad tiene algunas optimizaciones para detectar si existe una propiedad de recuento y, de ser así, úsela.Entonces ambos deberían hacer cosas casi idénticas. La propiedad Count probablemente sea un poco mejor, ya que no es necesario que haya una verificación de tipo allí.
fuente