views:

158

answers:

1

Hi!

Edit: I made a mistake in my original question. It should be about methods Last and LastOrDefault (or Single and SingleOrDefault, or First and FirstOrDefault - plenty of them!).

Inspired by this question, I opened Reflector and looked at code of

Enumerable.Last<T>(this collection)

Then I jumped to code of

Enumerable.LastOrDefault<T>(this collection)

and I saw exactly the same piece of code (about 20 lines) differing in only one last line (first method returns default(T), second throws exception).

My question is why it is so? Why guys in Microsoft allow duplication of non-trivial pieces of code inside .Net framework? Don't they have code review?

+4  A: 

In fact, they are not quite the same. The first is like this:

public static TSource Last<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw Error.ArgumentNull("source");

    IList<TSource> list = source as IList<TSource>;
    if (list != null) {
     int count = list.Count;
     if (count > 0) return list[count - 1];
    } else {
     using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
      if (enumerator.MoveNext()) {
       TSource current;
       do { current = enumerator.Current;}
       while (enumerator.MoveNext());

       return current;
      }
     }
    }
    throw Error.NoElements();
}

And the other is like this:

public static TSource Last<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");

    TSource last = default(TSource);
    bool foundOne = false;
    foreach (TSource value in source) {
     if (predicate(value)) {
      last = value;
      foundOne = true;
     }
    }
    if (!foundOne) throw Error.NoMatch();
    return last;
}

PS.: I hope I'm not breaking any copyrights now. :S

jpbochi
I meant Last and LastOrDefault. Thanks for spotting a bug in my question!
Konstantin Spirin
Considering the update, I see your point. The methods could be easily rewritten to avoid duplication. As for the reason they chosen not to do it, I have no idea. :S
jpbochi