Бывают случаи, когда полезно проверить неповторяемое IEnumerable
, чтобы увидеть, пусто оно или нет.LINQ Any
не подходит для этого, так как он потребляет первый элемент последовательности, например,
if(input.Any())
{
foreach(int i in input)
{
// Will miss the first element for non-repeatable sequences!
}
}
(Примечание: я знаю, что в этом случае нет необходимости выполнять проверку- это просто пример! Пример из реального мира - выполнение Zip
против правой руки IEnumerable
, которая потенциально может быть пустой. Если она пуста, я хочу, чтобы результатом был левый IEnumerable
as-есть.)
Я придумала потенциальное решение, которое выглядит следующим образом:
private static IEnumerable<T> NullifyIfEmptyHelper<T>(IEnumerator<T> e)
{
using(e)
{
do
{
yield return e.Current;
} while (e.MoveNext());
}
}
public static IEnumerable<T> NullifyIfEmpty<T>(this IEnumerable<T> source)
{
IEnumerator<T> e = source.GetEnumerator();
if(e.MoveNext())
{
return NullifyIfEmptyHelper(e);
}
else
{
e.Dispose();
return null;
}
}
Затем его можно использовать следующим образом:
input = input.NullifyIfEmpty();
if(input != null)
{
foreach(int i in input)
{
// Will include the first element.
}
}
IЕсть два вопроса по этому поводу:
1) Это разумно сделать?Это может быть проблематично с точки зрения производительности?(Наверное, нет, но стоит спросить.)
2) Есть ли лучший способ достижения той же конечной цели?
РЕДАКТИРОВАТЬ # 1:
Вот пример неповторяемого IEnumerable
, чтобы уточнить:
private static IEnumerable<int> ReadNumbers()
{
for(;;)
{
int i;
if (int.TryParse(Console.ReadLine(), out i) && i != -1)
{
yield return i;
}
else
{
yield break;
}
}
}
В основном, вещи, которые поступают из пользовательского ввода или потока и т. Д.
РЕДАКТИРОВАТЬ # 2:
Мне нужно уточнить, что я ищу решение, которое сохраняет ленивый характер IEnumerable
- преобразование его в список или массив может быть ответом при определенных обстоятельствах,но не то, что я здесь.(Реальная причина в том, что количество элементов в IEnumerable
может быть огромным в моем случае, и важно не хранить их все в памяти сразу.)