Чому метод Count () використовує ключове слово "перевірений"?


23

Переглядаючи різницю між графом і графом () , я подумав зазирнути на вихідний код Count(). Я побачив наступний фрагмент коду, в якому мені цікаво, чому checkedключове слово необхідне / потрібне:

int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        num = checked(num + 1);
    }
    return num;
}

Вихідний код:

// System.Linq.Enumerable
using System.Collections;
using System.Collections.Generic;

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
    }
    ICollection<TSource> collection = source as ICollection<TSource>;
    if (collection != null)
    {
        return collection.Count;
    }
    IIListProvider<TSource> iIListProvider = source as IIListProvider<TSource>;
    if (iIListProvider != null)
    {
        return iIListProvider.GetCount(onlyIfCheap: false);
    }
    ICollection collection2 = source as ICollection;
    if (collection2 != null)
    {
        return collection2.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num = checked(num + 1);
        }
        return num;
    }
}

2
.NET 4.0 ще не перевірив цю перевірку, 4,5. Дещо ймовірно, що це було зроблено, щоб уникнути проблем з ітераторами WinRT , зауважте, що вони використовують uint.
Ганс Пасант

Відповіді:


35

Оскільки він не хоче повернути від'ємне число у (мабуть, малоймовірному) випадку, якщо в послідовності є більше 2 мільярдів елементів, або непарне, але просто неправильне число у (ще більш неправдоподібному) випадку що в послідовності є більше 4 мільярдів елементів. checkedвиявить стан переливу.


1
@ DavidMårtensson C # за замовчуванням unchecked; він може бути перетворений checkedза замовчуванням на глобальному рівні за допомогою компілятора компілятора - але, чесно кажучи, я рідко бачу, що використовується, тому я думаю, що дуже неправильно припускати, що C # "зазвичай" працює в checkedрежимі; зауважте також, що unsafeне має взаємодії зunchecked
Марк Гравелл

1
Це було для мене новиною, я тестував це в проекті перед тим, як писати, і C # скаржився на переповнення, поки я не додав безперевірно навколо нього? Редагувати: знайшов відповідь на те, що я бачив "Для постійних виразів (виразів, які можна повністю оцінити під час компіляції), контекст за замовчуванням завжди перевіряється. Якщо постійний вираз явно не розміщений у неперевіреному контексті, переповнення, що виникають під час компіляції -часова оцінка виразу спричиняє помилки часу компіляції. "
Девід Мартенсон

@ DavidMårtensson ах, так - хороший нюанс; Я говорив про час виконання; як ви кажете: час компіляції відрізняється
Марк Гравелл

Але час компіляції не застосовується для прикладу публікації, тому мій коментар був невірним, і я його видалив.
Девід Мартенсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.