Por que o método Count () usa a palavra-chave "marcada"?

23

Como eu estava olhando a diferença entre Count e Count () , pensei em olhar o código fonte de Count(). Eu vi o seguinte trecho de código no qual me pergunto por que a checkedpalavra-chave é necessária / necessária:

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

O código fonte:

// 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;
    }
}
snr - Restabelecer Monica
fonte
2
O .NET 4.0 ainda não tinha essa verificação, e a 4.5. Torna um pouco provável que isso tenha sido feito para evitar problemas com os iteradores do WinRT , observe que eles usam o uint.
Hans Passant

Respostas:

35

Porque ele não deseja retornar um número negativo no evento (reconhecidamente improvável) de que há mais de 2 bilhões de itens ímpares na sequência - ou um número não negativo, mas apenas errado no caso (ainda mais improvável) que existem mais de 4 bilhões de itens ímpares na sequência. checkeddetectará a condição de estouro.

Marc Gravell
fonte
11
@ DavidMårtensson C # assume como padrão unchecked; ele pode ser ativado checkedpor padrão no nível global por meio de uma opção de compilador - mas, francamente, raramente vejo isso sendo usado, por isso acho muito errado sugerir que o C # é "geralmente" executado no checkedmodo; observe também que unsafenão tem interação comunchecked
Marc Gravell
11
Isso foi novidade para mim, eu testei isso em um projeto antes de escrever e o C # reclamou do estouro até adicionar desmarcado? Editar: Encontrei a resposta para o que eu vi "Para expressões constantes (expressões que podem ser totalmente avaliadas em tempo de compilação), o contexto padrão é sempre verificado. A menos que uma expressão constante seja explicitamente colocada em um contexto não verificado, os estouros que ocorrem durante a compilação A avaliação da expressão em tempo real causa erros em tempo de compilação. "
David Mårtensson
@ DavidMårtensson ah, sim - boas nuances; Eu estava falando sobre tempo de execução; como você diz: o tempo de compilação é diferente
Marc Gravell
Mas o tempo de compilação não se aplica ao exemplo da postagem, portanto meu comentário estava incorreto e eu o apaguei.
David Mårtensson