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 Countpropiedad en las declaraciones condicionales porque supongo que el Count()método realiza algún tipo de consulta contra la colección, donde ya Countdebe 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 Countpropiedad 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 subyacenteCountpropiedad :Por lo tanto, si su código accede en
Countlugar 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 laICollectioninterfaz 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.County 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.Countpropiedad .Entonces de nuevo, tal vez no.
Yo diría que es seguro asumir que si la colección tiene una
.Countpropiedad 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
Countpropiedad podría ser mejor, pero el uso deCount()métodosICollection<T>.Countestá 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 deIEnumerablees en realidad aList<>, entonces está optimizada para devolver laCountpropiedad en lugar de iterar todos los elementos.fuente
Count()¿Existe como un método de extensión de LINQ?Countes una propiedad enLists, 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
Countpropiedad 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
Countpropiedad 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
CountoLength, 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 unaCountpropiedad, 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