Pregunta

Tenía curiosidad por ver cómo se implementó el método SingleOrFallback en MoreLinq y descubrí algo yo no había visto antes:

    public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
    {
        source.ThrowIfNull("source");
        fallback.ThrowIfNull("fallback");
        using (IEnumerator<T> iterator = source.GetEnumerator())
        {
            if (!iterator.MoveNext())
            {
                return fallback();
            }
            T first = iterator.Current;
            if (iterator.MoveNext())
            {
                throw new InvalidOperationException();
            }
            return first;
        }
    }

¿Por qué el IEnumerator<T> en un comunicado using? Es algo que se debe pensar sobre cuando se utiliza el foreach en una IEnumerable<T> también?

pregunta al margen: ¿Qué hace exactamente este método? ¿Vuelve el elemento de respaldo cada vez que la secuencia de origen no contiene exactamente un artículo?

¿Fue útil?

Solución

IEnumerator<T> extiende IDisposable, por lo que debe tenerlo en una instrucción using. foreach lo hace automáticamente. (El IEnumerator no genérico no se extienden IDisposable pero el compilador de C # todavía genera código para llamar Dispose condicional. Este fue uno de los pocos cambios () entre C # 1.0 y 1.2, donde 1.2 es la versión el envío con .NET 1.1, por alguna razón.)

He aquí un artículo explicando por qué esto es importante en el contexto de los bloques de iterador.

En cuanto a lo que hace el método:

  • Si la secuencia está vacía, la devolución del artículo de retorno
  • Si la secuencia tiene exactamente un elemento, devolverlo
  • Si la secuencia tiene más de un elemento, una excepción

PS: Es bueno ver MoreLinq está recibiendo algo de atención:)

Otros consejos

Algunos encuestadores se comportan mal si no se llama Desechar; esto es tan cierto para los no genéricos como los genéricos (los que no genéricas requieren que el código sea de tipo pato de la llamada Desechar o yeso para IDisposable y luego llamar IDisposable.Dispose otra cosa). Es bueno como una cuestión de costumbre para asegurar que los objetos IEnumerator consiguen dispuestos; Lo consideraría necesario para la corrección de cualquier rutina que acepta un IEnumerable de tipo desconocido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top