Domanda

ero curioso di vedere come il metodo SingleOrFallback è stato attuato nel MoreLinq e ha scoperto qualcosa non avevo mai visto prima:

    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;
        }
    }

Perché il IEnumerator<T> in un comunicato using? E 'questo qualcosa che dovrebbe essere pensato di quando si utilizza il foreach su un IEnumerable<T> anche?

domanda laterale: Che cosa significa questo metodo esattamente fare? Ha ritorno l'articolo fallback ogni volta che la sequenza di origine non contiene esattamente un articolo?

È stato utile?

Soluzione

IEnumerator<T> estende IDisposable, in modo da dovrebbe avere in un'istruzione using. foreach lo fa automaticamente. (Il IEnumerator non generico non si estendono IDisposable ma il compilatore C # genera ancora il codice per chiamare Dispose condizionale. Questa è stata una delle (poche) modifiche tra C # 1.0 e 1.2, dove 1.2 è la versione spedizione con .NET 1.1, per qualche ragione.)

Ecco un articolo spiegando il motivo per cui questo è importante nel contesto di blocchi iteratore.

Per quanto riguarda ciò che il metodo fa:

  • Se la sequenza è vuota, restituire l'oggetto fallback
  • Se la sequenza ha esattamente un elemento, restituirlo
  • Se la sequenza è più di un oggetto, un'eccezione

PS: Bello vedere MoreLinq sta ottenendo una certa attenzione:)

Altri suggerimenti

Alcuni enumeratori si comporteranno male se Dispose non è chiamato; questo è altrettanto vero per quelli non generici come quelli generici (quelli non generici richiedono che il codice sia anatra tipo chiamata Dispose oppure cast IDisposable e quindi chiamare IDisposable.Dispose). E 'bene come una questione di abitudine per garantire che gli oggetti IEnumerator ottenere disposta; Vorrei prendere in considerazione necessario per correttezza di qualsiasi routine che accetta un IEnumerable di tipo sconosciuto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top