Is there a way to know I am getting the last element in the foreach loop

Only way I know of is to increment a counter and compare with length on exit, or when breaking out of loop set a boolean flag, loopExitedEarly.


There isn't a direct way. You'll have to keep buffering the next element.

IEnumerable<Foo> foos = ...

Foo prevFoo = default(Foo);
bool elementSeen = false;

foreach (Foo foo in foos)
{
    if (elementSeen) // If prevFoo is not the last item...
        ProcessNormalItem(prevFoo);

    elementSeen = true;
    prevFoo = foo;
}

if (elementSeen) // Required because foos might be empty.
    ProcessLastItem(prevFoo);

Alternatively, you could use the underlying enumerator to do the same thing:

using (var erator = foos.GetEnumerator())
{
    if (!erator.MoveNext())
        return;

    Foo current = erator.Current;

    while (erator.MoveNext())
    {
        ProcessNormalItem(current);
        current = erator.Current;
    }

    ProcessLastItem(current);
}

It's a lot easier when working with collections that reveal how many elements they have (typically the Count property from ICollection or ICollection<T>) - you can maintain a counter (alternatively, if the collection exposes an indexer, you could use a for-loop instead):

int numItemsSeen = 0;

foreach(Foo foo in foos)
{
   if(++numItemsSeen == foos.Count)
       ProcessLastItem(foo)

   else ProcessNormalItem(foo);
}

If you can use MoreLinq, it's easy:

foreach (var entry in foos.AsSmartEnumerable())
{
    if(entry.IsLast)
       ProcessLastItem(entry.Value)

    else ProcessNormalItem(entry.Value);
}

If efficiency isn't a concern, you could do:

Foo[] fooArray = foos.ToArray();

foreach(Foo foo in fooArray.Take(fooArray.Length - 1))
    ProcessNormalItem(foo);

ProcessLastItem(fooArray.Last());

Tags:

C#

.Net