C# Language Comprobando correctamente los argumentos


Ejemplo

Un método iterador no se ejecuta hasta que se enumera el valor de retorno. Por lo tanto, es ventajoso afirmar condiciones previas fuera del iterador.

public static IEnumerable<int> Count(int start, int count)
{
    // The exception will throw when the method is called, not when the result is iterated
    if (count < 0)
        throw new ArgumentOutOfRangeException(nameof(count));

    return CountCore(start, count);
}

private static IEnumerable<int> CountCore(int start, int count)
{
    // If the exception was thrown here it would be raised during the first MoveNext()
    // call on the IEnumerator, potentially at a point in the code far away from where
    // an incorrect value was passed.
    for (int i = 0; i < count; i++)
    {
        yield return start + i;
    }
}

Código lateral de llamada (uso):

// Get the count
var count = Count(1,10);
// Iterate the results
foreach(var x in count)
{
    Console.WriteLine(x);
}

Salida:

1
2
3
4
5
6
7
8
9
10

Demo en vivo en .NET Fiddle

Cuando un método utiliza el yield para generar un enumerable, el compilador crea una máquina de estado que, cuando se itera, ejecuta el código hasta un yield . A continuación, devuelve el elemento cedido y guarda su estado.

Esto significa que no encontrará información sobre argumentos no válidos (pasar null etc.) cuando llame por primera vez al método (porque eso crea la máquina de estado), solo cuando intente acceder al primer elemento (porque solo entonces el código dentro de la método se ejecuta por la máquina de estado). Al ajustarlo en un método normal que primero verifica los argumentos, puede verificarlos cuando se llama al método. Este es un ejemplo de fallar rápido.

Cuando se usa C # 7+, la función CountCore se puede ocultar convenientemente en la función Count como una función local . Vea el ejemplo aquí .