Pourquoi la méthode Count () utilise-t-elle le mot-clé «vérifié»?

23

Comme je cherchais la différence entre Count et Count () , j'ai pensé à jeter un coup d'œil au code source de Count(). J'ai vu l'extrait de code suivant dans lequel je me demande pourquoi le checkedmot clé est nécessaire / nécessaire:

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

Le code source:

// 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 - Réintégrer Monica
la source
2
.NET 4.0 n'avait pas encore cette vérification, 4.5 en avait. Rend quelque peu probable que cela a été fait pour éviter les problèmes avec les itérateurs WinRT , notez qu'ils utilisent uint.
Hans Passant

Réponses:

35

Parce qu'il ne veut pas retourner un nombre négatif dans le cas (certes peu probable) où il y a plus de 2 milliards d'articles impairs dans la séquence - ou un nombre non négatif mais juste faux dans le cas (encore plus improbable) qu'il y a plus de 4 milliards d'articles impairs dans la séquence. checkeddétectera la condition de débordement.

Marc Gravell
la source
1
@ DavidMårtensson C # par défaut unchecked; il peut être inversé checkedpar défaut au niveau global via un commutateur de compilation, mais - franchement, je le vois rarement utilisé, donc je pense qu'il est très faux de suggérer que C # est "généralement" exécuté en checkedmode; à noter également qui unsafen'a pas d'interaction avecunchecked
Marc Gravell
1
C'était une nouveauté pour moi, j'ai testé cela dans un projet avant d'écrire et C # s'est plaint de débordement jusqu'à ce que j'ajoute non contrôlé autour de lui? Edit: J'ai trouvé la réponse à ce que j'ai vu "Pour les expressions constantes (expressions qui peuvent être entièrement évaluées au moment de la compilation), le contexte par défaut est toujours vérifié. Sauf si une expression constante est explicitement placée dans un contexte non contrôlé, les débordements qui se produisent pendant la compilation -l'évaluation de l'expression provoque des erreurs de compilation. "
David Mårtensson
@ DavidMårtensson ah, oui - bonne nuance; Je parlais de l'exécution; comme vous le dites: la compilation est différente
Marc Gravell
Mais le temps de compilation ne s'applique pas à l'exemple de la publication, mon commentaire était donc incorrect et je l'ai supprimé.
David Mårtensson