Вопрос

Мне было любопытно посмотреть, как SingleOrFallback метод был реализован в ПодробнееLinq и обнаружил то, чего раньше не видел:

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

Почему IEnumerator<T> в using заявление?Стоит ли об этом думать при использовании foreach на IEnumerable<T> также?

Побочный вопрос: Что конкретно делает этот метод?Возвращает ли он резервный элемент всякий раз, когда исходная последовательность не содержит ровно одного элемента?

Это было полезно?

Решение

IEnumerator<T> простирается IDisposable, так что вы должен используйте это в операторе использования. foreach делает это автоматически.(Необщий IEnumerator не делает продлевать IDisposable но компилятор C# по-прежнему генерирует код для вызова Dispose условно.Это было одно из (немногих) изменений между C# 1.0 и 1.2, где 1.2 по какой-то причине — это версия, поставляемая с .NET 1.1.)

Вот статья объясняя, почему это важно в контексте блоков итераторов.

Что касается того, что делает метод:

  • Если последовательность пуста, верните резервный элемент.
  • Если в последовательности ровно один элемент, верните его.
  • Если последовательность содержит более одного элемента, выдайте исключение

ПС:Приятно видеть, что MoreLinq привлекает внимание :)

Другие советы

Некоторые перечислители будут вести себя плохо, если Dispose не вызываться;это так же верно как для неуниверсальных, так и для универсальных (неуниверсальные требуют, чтобы код либо вводил вызов Dispose, либо приводил его к IDisposable, а затем вызывал IDisposable.Dispose).По привычке рекомендуется обеспечить удаление объектов IEnumerator;Я бы посчитал это необходимым для корректности любой процедуры, которая принимает IEnumerable неизвестного типа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top