Вы можете создать вспомогательный метод (я создал его как метод расширения), чтобы гарантировать, что он повторяется только один раз:
public static class LinqExtensions
{
public static bool DoIfAny<T>(this IEnumerable<T> collection, Action<IEnumerable<T>> action)
{
var enumerator = collection.GetEnumerator();
if (!enumerator.MoveNext())
{
return false;
}
action(CreateEnumerableFromStartedEnumerable(enumerator));
return true;
}
private static IEnumerable<T> CreateEnumerableFromStartedEnumerable<T>(IEnumerator<T> enumerator)
{
do
{
yield return enumerator.Current;
}
while (enumerator.MoveNext());
}
}
По сути, это создаст перечислитель для коллекции, а затем попытается перейти к первому элементу. Если это не удается, метод не вызывается, а возвращается false
.
В случае успеха создается новое перечисляемое число, которое выполняет итерацию остальной части перечисляемого источника, выдавая его значения по ходу выполнения. Это включает самое первое значение. Затем он будет передан делегату действия, и true
будет возвращено.
Использование:
IEnumerable<string> values = new string[] { "a", "b", "c" };
bool delegateCalled = values.DoIfAny(e => DoStuff(e));
Console.WriteLine("Delegate called: " + delegateCalled.ToString());
Попробуйте онлайн
Примечание что это действительно будет работать, только если вы хотите .Any()
в смысле «коллекция не пуста». Если он проверяет наличие определенного элемента c, тогда вам нужно сначала материализовать список, как в ответе Тао.