C #: IEnumerator dans une déclaration à l'aide
-
06-09-2019 - |
Question
Je suis curieux de voir comment la méthode SingleOrFallback
a été mis en œuvre dans MoreLinq et découvert quelque chose Je ne l'avais pas vu auparavant:
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;
}
}
Pourquoi le IEnumerator<T>
dans un communiqué de using
? Est-ce quelque chose qui doit être pensé lors de l'utilisation du foreach
sur un IEnumerable<T>
aussi?
question de côté: Qu'est-ce que cette méthode exactement? Est-il revenir l'élément de secours chaque fois que la séquence source ne contient pas exactement un élément?
La solution
IEnumerator<T>
étend IDisposable
, de sorte que vous devez ont dans une déclaration à l'aide. foreach
fait automatiquement. (Le IEnumerator
non générique ne pas étendre IDisposable
mais le compilateur C # génère encore du code pour appeler Dispose
conditionnelle. Ce fut l'un des (rares) changements entre C # 1.0 et 1.2, où 1.2 est la version expédition avec .NET 1.1, pour une raison quelconque.)
Voici un article expliquant pourquoi il est important dans le contexte des blocs itérateur.
Quant à ce que la méthode fait:
- Si la séquence est vide, retourner l'élément de secours
- Si la séquence a exactement un élément, retourner
- Si la séquence a plus d'un élément, lancer une exception
PS: Nice voir MoreLinq est une certaine attention:)
Autres conseils
Certains agents recenseurs se comportent mal si Dispose est pas appelé; cela est tout aussi vrai pour les non génériques que les génériques (les non génériques requièrent que le code soit de type de canard l'appel Éliminez ou bien jeter à IDisposable puis appeler IDisposable.Dispose). Il est bon que par habitude de faire en sorte que les objets IEnumerator obtenir disposés; Je considère qu'il est nécessaire pour l'exactitude de toute routine qui accepte un IEnumerable de type inconnu.