You could create a helper method (I've created this as an extension method) to ensure that it's only iterated once:
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());
}
}
Essentially this will create an enumerator for the collection, and then try to move to the first item. If that fails, then the method is not called and false
is returned.
If it's successful, then it will produce a new enumerable which iterates the rest of the source enumerable, yielding its values as it goes. This includes the very first value. This will then be passed to an action delegate and true
will be returned.
Usage:
IEnumerable<string> values = new string[] { "a", "b", "c" };
bool delegateCalled = values.DoIfAny(e => DoStuff(e));
Console.WriteLine("Delegate called: " + delegateCalled.ToString());
Try it online
Note that this will only really work if you want .Any()
in the sense of "the collection isn't empty". If it is checking for the existence of a specific element, then you'll have to materialise the list first as in Tao's answer.