Warum verwendet die Count () -Methode das Schlüsselwort "checked"?

23

Als ich den Unterschied zwischen Count und Count () sah , dachte ich daran, einen Blick auf den Quellcode von zu werfen Count(). Ich habe den folgenden Codeausschnitt gesehen, in dem ich mich frage, warum das checkedSchlüsselwort notwendig / benötigt wird:

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

Der Quellcode:

// 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 - Monica wieder einsetzen
quelle
2
.NET 4.0 hatte diese Prüfung noch nicht, 4.5 schon. Macht es eher wahrscheinlich , dass dies wurde getan , um zu vermeiden Ärger mit WinRT Iteratoren , zur Kenntnis , dass sie uint verwenden.
Hans Passant

Antworten:

35

Weil es im (zugegebenermaßen unwahrscheinlichen) Fall, dass die Sequenz mehr als 2 Milliarden Elemente enthält, keine negative Zahl zurückgeben möchte - oder im (noch unwahrscheinlicheren) Fall eine nicht negative, aber nur falsche Zahl dass es mehr als 4 Milliarden ungerade Elemente in der Sequenz gibt. checkederkennt den Überlaufzustand.

Marc Gravell
quelle
1
@ DavidMårtensson C # ist standardmäßig unchecked; Es kann jedoch checkedstandardmäßig auf globaler Ebene über einen Compiler-Schalter umgeschaltet werden - aber ehrlich gesagt sehe ich das selten verwendet, daher halte ich es für sehr falsch zu behaupten, dass C # "normalerweise" im checkedModus ausgeführt wird; Beachten Sie auch, dass unsafekeine Interaktion mitunchecked
Marc Gravell
1
Das war eine Neuigkeit für mich, ich habe dies in einem Projekt getestet, bevor ich geschrieben habe, und C # hat sich über Überlauf beschwert, bis ich es ungeprüft hinzugefügt habe? Bearbeiten: Ich habe die Antwort auf das gefunden, was ich gesehen habe: "Bei konstanten Ausdrücken (Ausdrücke, die zur Kompilierungszeit vollständig ausgewertet werden können) wird der Standardkontext immer überprüft. Sofern ein konstanter Ausdruck nicht explizit in einem ungeprüften Kontext platziert wird, treten Überläufe auf, die während der Kompilierung auftreten -Zeitauswertung des Ausdrucks verursacht Fehler bei der Kompilierung. "
David Mårtensson
@ DavidMårtensson ah, ja - gute Nuance; Ich habe über Laufzeit gesprochen; wie Sie sagen: Die Kompilierungszeit ist anders
Marc Gravell
Die Kompilierungszeit gilt jedoch nicht für das Beispiel des Beitrags, sodass mein Kommentar falsch war und ich ihn gelöscht habe.
David Mårtensson