This might be a little too much, but I think it's elegant.
Creating an extension method for IEnumerable<T>
that takes an Action<T>
for each type of item, we can make a loop like this:
int sum = 0;
collection.IEnumForEachItem(
firstItem =>
{
//do things for first item
sum = firstItem.SomeProperty;
},
midItem =>
{
doThingsForIntermediate(midItem);
sum += midItem.SomeProperty * 2;
},
lastItem =>
{
if (lastItem.SomeProperty > 10);
sum += 10;
else
sum += lastItem.SomeProperty;
}
);
This is the extension method (it must be in a static class):
public static void IEnumForEachItem<T>(this IEnumerable<T> items,
Action<T> actionForFirstItem, Action<T> actionForMidItems, Action<T> actionForLastItem)
{
using (IEnumerator<T> enumerator = items.GetEnumerator())
{
if (enumerator.MoveNext())
actionForFirstItem(enumerator.Current);
if (!enumerator.MoveNext())
throw new InvalidOperationException("IEnumerable must have at least 2 items");
T currentItem = enumerator.Current;
while (enumerator.MoveNext())
{
actionForMidItems(currentItem);
currentItem = enumerator.Current;
}
actionForLastItem(currentItem);
}
}
From this it's easy to make methods that take only "first and others" and also "others and last".
last
, aka the previous item, not the current one – Jamnes