¿Por qué el método Count () usa la palabra clave "marcada"?


23

Mientras buscaba la diferencia entre Count y Count () , pensé en mirar el código fuente de Count(). Vi el siguiente fragmento de código en el que me pregunto por qué la checkedpalabra clave es necesaria / necesaria:

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

El código fuente:

// 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 todavía no tenía esta verificación, 4.5 sí. Hace algo probable que esto se haya hecho para evitar problemas con los iteradores WinRT , tenga en cuenta que usan uint.
Hans Passant

Respuestas:


35

Debido a que no quiere devolver un número negativo en el evento (ciertamente improbable) de que haya más de 2 mil millones de elementos impares en la secuencia, o un número no negativo pero simplemente incorrecto en el caso (aún más improbable) que hay más de 4 mil millones de artículos impares en la secuencia. checkeddetectará la condición de desbordamiento.


1
@ DavidMårtensson C # por defecto es unchecked; sin embargo, se puede cambiar a checkednivel global a través de un conmutador de compilación, pero, francamente, rara vez veo que se usa, por lo que creo que es muy incorrecto sugerir que C # se ejecuta "normalmente" en checkedmodo; tenga en cuenta también que unsafeno tiene interacción conunchecked
Marc Gravell

1
Eso fue nuevo para mí, probé esto en un proyecto antes de escribir y C # se quejó del desbordamiento hasta que agregué sin marcar. Editar: Encontré la respuesta a lo que vi "Para expresiones constantes (expresiones que se pueden evaluar completamente en tiempo de compilación), el contexto predeterminado siempre se verifica. A menos que una expresión constante se coloque explícitamente en un contexto no verificado, se producen desbordamientos durante la compilación evaluación en tiempo de la expresión causa errores en tiempo de compilación ".
David Mårtensson

@ DavidMårtensson ah, sí, buenos matices; Estaba hablando de tiempo de ejecución; como usted dice: el tiempo de compilación es diferente
Marc Gravell

Pero el tiempo de compilación no se aplica al ejemplo de la publicación, por lo que mi comentario fue incorrecto y lo he eliminado.
David Mårtensson
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.