Last()
will call GetEnumerator()
, then keep calling MoveNext()
/ Current
until MoveNext()
returns false, at which point it returns the last value of Current
retrieved. Nullity is not used as a terminator in sequences, generally.
So the implementation might be something like this:
public static T Last<T>(this IEnumerable<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("Empty sequence");
}
T value = iterator.Current;
while (iterator.MoveNext())
{
value = iterator.Current;
}
return value;
}
}
(This could be implemented with a foreach
loop, but the above shows the interaction more explicitly. This also ignores the possibility of accessing the last element directly.)