Свойство Count против метода Count ()? - PullRequest
69 голосов
/ 01 ноября 2011

Работа с коллекцией У меня есть два способа получить количество объектов;Count (свойство) и Count () метод.Кто-нибудь знает, каковы основные различия?Я могу ошибаться, но я всегда использую свойство Count в любых условных выражениях, потому что я предполагаю, что метод Count () выполняет какой-то запрос к коллекции, так как Count должен быть уже назначен до того, как я получил.Но это предположение - я не знаю, повлияет ли это на производительность, если я ошибаюсь.

РЕДАКТИРОВАТЬ: Из любопытства, тогда Count () выдаст исключение, если коллекция пуста?Потому что я уверен, что свойство Count просто возвращает 0.

Ответы [ 8 ]

91 голосов
/ 01 ноября 2011

Декомпиляция источника для метода расширения Count() показывает, что он проверяет, является ли объект ICollection (универсальным или иным) и, если это так, просто возвращает базовое свойство Count:

Итак,если ваш код обращается к Count вместо вызова Count(), вы можете обойти проверку типов - теоретическое преимущество в производительности, но я сомневаюсь, что оно будет заметным!

// 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;
    }
}
29 голосов
/ 03 октября 2012

Производительность - это только одна причина, чтобы выбрать один или другой.Выбор .Count () означает, что ваш код будет более общим.У меня были случаи, когда я реорганизовывал некоторый код, который больше не создавал коллекцию, но вместо этого что-то более общее, например, IEnumerable, но в результате другой код сломался, поскольку он зависел от .Count, и мне пришлось изменить его на .Count(),Если бы я решил использовать .Count() везде, код, вероятно, был бы более пригоден для повторного использования и поддержки.Обычно лучше использовать более общие интерфейсы, если вы можете сойти с рук.Под более общим я подразумеваю более простой интерфейс, который реализован большим количеством типов, и, таким образом, обеспечивает большую совместимость кода.

Я не говорю, что .Count() лучше, я просто говорю, что есть и другие соображения.это больше касается возможности повторного использования кода, который вы пишете.

18 голосов
/ 01 ноября 2011

Метод .Count() может быть достаточно умным или знать о рассматриваемом типе, и в этом случае он может использовать базовое свойство .Count.

Опять же, это может быть не так.

Я бы сказал, что можно с уверенностью предположить, что если коллекция имеет само свойство .Count, это будет лучшим выбором для производительности.

Если метод .Count() не знает о коллекции, он будет перечислять ее, что будет операцией O (n).

5 голосов
/ 01 ноября 2011

Метод Count () - это метод расширения, который выполняет итерацию каждого элемента IEnumerable <> и возвращает количество элементов. Если экземпляр IEnumerable на самом деле является List <>, он оптимизирован для возврата свойства Count вместо итерации всех элементов.

3 голосов
/ 01 ноября 2011

Если есть свойство Count или Length, вы всегда должны предпочитать его методу Count (), который обычно выполняет итерацию всей коллекции для подсчета количества элементов внутри. (Исключения могут быть, например, когда метод Count () работает с источником Linq to SQL или Linq to Entities, и в этом случае он будет выполнять запрос счетчика к источнику данных. Даже тогда, если есть свойство Count, вы бы хочу предпочесть это, так как, вероятно, у него меньше работы.)

2 голосов
/ 01 ноября 2011

Короткая версия: Если у вас есть выбор между свойством Count и методом Count(), всегда выбирайте это свойство.

Разница в основном заключается в эффективности операции.Все коллекции BCL, которые предоставляют свойство Count, делают это O (1).Однако метод Count() может стоить и часто будет стоить O (N).Есть некоторые проверки, чтобы попытаться получить его в O (1) для некоторых реализаций, но это ни в коем случае не гарантировано.

2 голосов
/ 01 ноября 2011

Метод Count () - это метод LINQ, который работает на любом IEnumerable <>. Можно ожидать, что метод Count () будет перебирать всю коллекцию, чтобы найти счетчик, но я полагаю, что в коде LINQ есть некоторые оптимизации, позволяющие определить, существует ли свойство Count и, если да, то использовать его.

Так что они оба должны делать почти идентичные вещи. Свойство Count, вероятно, немного лучше, поскольку здесь не требуется проверка типа.

1 голос
/ 01 ноября 2011

Count() существует как метод расширения из LINQ - Count является свойством List s, фактические объекты коллекции .NET.

Таким образом, Count() почти всегда будет медленнее, поскольку будет перечислять объект коллекции / запрашиваемый объект. В списке, очереди, стеке и т. Д. Используйте Count. Или для массива - Length.

...