C #: IEnumerator in un'istruzione using
-
06-09-2019 - |
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?
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.