The public static TSource Last<TSource>(this IEnumerable<TSource> source) extension method for IEnumerable<TSource> uses optimization for a source of the IList<TSource> type so that it does not iterate over the whole sequence when it can just step at the end using indexing.
IList<TSource> tSources = source as IList<TSource>;
if (tSources != null)
{
int count = tSources.Count;
if (count > 0)
{
return tSources[count - 1];
}
}
I slightly altered the code so that it is mroe readable, but the functionality remains the same.
Why is not public static TSource Last<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) also optimized when it could clearly start iterating from the end of the sequence?
If there should be something that matches the predicate and it is near the start of the sequence then I still need to iterate to the very end. If there is something matching at the end I don't have to iterate more, because I started from the end.
I would expect something like this being a part of the method.
IList<TSource> tSources = source as IList<TSource>;
if (tSources != null)
{
int count = tSources.Count;
if (count > 0)
{
for (int i = count - 1; i >= 0; i--)
{
if (predicate(tSources[i]))
{
return tSources[i];
}
}
}
}