Я не знаю, позволяет ли ваш алгоритм в Foo
определить, будет ли перечисление пустым, без выполнения вычислений.Но если это так, верните null
, если последовательность будет пустой:
public IEnumerable<T> Foo()
{
if (<check if sequence will be empty>) {
return null;
}
return GetSequence();
}
private IEnumerable<T> GetSequence()
{
...
yield return item;
...
}
Обратите внимание, что если метод использует yield return
, он не может использовать простой return
для возврата null
,Поэтому необходим второй метод.
var sequence = Foo();
if (sequence != null) {
Bar(sequence);
}
После прочтения одного из ваших комментариев
Foo необходимо инициализировать некоторые ресурсы, проанализировать XML-файл и заполнить некоторые HashSets, которыебудет использоваться для фильтрации (выдачи) возвращаемых данных.
Я предлагаю другой подход.Трудоемкая часть, кажется, инициализация.Чтобы иметь возможность отделить его от итерации, создайте класс калькулятора foo.Что-то вроде:
public class FooCalculator<T>
{
private bool _isInitialized;
private string _file;
public FooCalculator(string file)
{
_file = file;
}
private EnsureInitialized()
{
if (_isInitialized) return;
// Parse XML.
// Fill some HashSets.
_isInitialized = true;
}
public IEnumerable<T> Result
{
get {
EnsureInitialized();
...
yield return ...;
...
}
}
}
Это гарантирует, что дорогостоящая инициализация выполняется только один раз.Теперь вы можете безопасно использовать Any()
.
Возможны другие варианты оптимизации.Свойство Result
может запоминать позицию первого возвращаемого элемента, поэтому, если он вызывается снова, он может сразу перейти к нему.