Как сказать, подвергается ли IEnumerable <T> задержанному выполнению?

Добавить опцию --force :

mysql -u username -p database_name --force < file.sql

28
задан nawfal 28 September 2013 в 14:38
поделиться

5 ответов

Отложенное выполнение LINQ задержало множество людей, и вы не одиноки.

Я использовал следующий подход, чтобы избежать этой проблемы:

Параметры методов - используйте IEnumerable , если нет необходимости в более конкретном интерфейсе.

Локальные переменные - обычно в точке, где я создаю LINQ, поэтому я буду знать, буду ли возможны ленивые вычисления.

Члены класса - никогда не используйте IEnumerable , всегда используйте List . И всегда делайте их закрытыми.

Свойства - используйте IEnumerable и конвертируйте для хранения в установщике.

public IEnumerable<Person> People 
{
    get { return people; }
    set { people = value.ToList(); }
}
private List<People> people;

Хотя есть теоретические случаи, когда этот подход не работает, Я еще ни с одним не встречался, и я я с энтузиазмом использовал методы расширения LINQ с поздней бета-версии.

Кстати: мне любопытно, почему вы используете ToArray (); вместо ToList (); - для меня, списки имеют гораздо более приятный API и (почти) не требуют затрат на производительность.

Обновление : пара комментаторов справедливо отметила, что массивы имеют теоретическое преимущество в производительности, поэтому я изменил свое утверждение выше на " ... там (почти) нет затрат на производительность ".

Обновление 2 : Я написал код для микротестирования разницы в производительности между массивами и списками. На моем ноутбуке и в моем конкретном тесте разница составляет около 5 нс (это нано секунд) на доступ. Думаю, есть случаи, когда стоит экономить 5 нс на цикл ... но я никогда не сталкивался с таким.

19
ответ дан 28 November 2019 в 03:42
поделиться

Сообщение о расширении представления результатов для оценки коллекции является стандартным сообщением, представленным для всех IEnumerable объектов. Я не уверен, что существуют какие-либо надежные средства проверки того, является ли IEnumerable отложенным, главным образом потому, что даже yield является отложенным. Единственный способ полностью гарантировать , что это не отложено, - это принять ICollection или IList .

.
2
ответ дан 28 November 2019 в 03:42
поделиться

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

Потоковый характер выполнения IEnumerable имеет преимущества. . Это правда - бывают случаи, когда это невыгодно, но я бы рекомендовал всегда обрабатывать эти (редкие) времена специально - либо используйте ToList () , либо ToArray () , чтобы преобразовать его в список или массив, в зависимости от ситуации.

В остальное время лучше просто отложить это. Необходимость часто проверять это кажется более серьезной проблемой дизайна ...

7
ответ дан 28 November 2019 в 03:42
поделиться

Вполне возможно вручную реализовать ленивый IEnumerator , поэтому не существует "совершенно общего" способа сделать это. Я имею в виду следующее: если я меняю что-то в списке, перечисляя что-то связанное с ним, всегда вызывайте ToArray () перед foreach .

1
ответ дан 28 November 2019 в 03:42
поделиться

Это интересная реакция на отложенное выполнение - большинство людей рассматривают ее как положительную, поскольку она позволяет вам преобразовывать потоки данных без необходимости их буферизации.

Предложенный вами тест выиграл не работает, потому что нет причин, по которым метод итератора не может выдавать тот же экземпляр ссылочного объекта, что и его первый объект, при двух последовательных попытках.

IEnumerable<string> Names()
{
    yield return "Fred";
}

Это будет возвращать тот же статический строковый объект каждый раз, как единственный элемент в последовательность.

Поскольку вы не можете надежно определить сгенерированный компилятором класс, который возвращается из метода итератора, вам придется сделать обратное: проверить несколько хорошо известных контейнеров:

public static IEnumerable<T> ToNonDeferred(this IEnumerable<T> source)
{
    if (source is List<T> || source is T[]) // and any others you encounter
        return source;

    return source.ToArray();
}

Вернув IEnumerable , мы сохраняем коллекцию только для чтения, что важно, потому что мы можем получить обратно копию или оригинал.

1
ответ дан 28 November 2019 в 03:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: