0
\$\begingroup\$

What do you think of my own implementation of the extension method SelectMany? Motivating criticism is always welcome.

public static IEnumerable<TResult> MySelectMany<T, TResult>(this IEnumerable<T> source, Func<T, IEnumerable<TResult>> selector)
{
    var theList = new List<TResult>();

    foreach (T item in source)
    {
        foreach (TResult inneritem in selector(item))
        {
            theList.Add(inneritem);
        }
    }

    return theList as IEnumerable<TResult>;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ You're doing this just as a learning exercise, right? Otherwise, reimplementing framework code doesn't make much sense. \$\endgroup\$ – svick Jul 25 '12 at 10:35
  • \$\begingroup\$ Just to learn indeed. Fooling around with extension methods and delegates etc... :) \$\endgroup\$ – HerbalMart Jul 25 '12 at 10:40
  • 2
    \$\begingroup\$ For a detailed explanation about how to implement all of LINQ extension methods, see Jon Skeet's series Edulinq. Specifically, part 9 is about SelectMany(). \$\endgroup\$ – svick Jul 25 '12 at 11:06
7
\$\begingroup\$

The as cast in the return statement is entirely redundant, it doesn’t serve a purpose.

Furthermore, The problem with this implementation is that it’s not lazy. You should use a yield generator instead.

public static IEnumerable<TResult> MySelectMany<T, TResult>(this IEnumerable<T> source, Func<T, IEnumerable<TResult>> selector)
{
    foreach (T item in source)
        foreach (TResult inneritem in selector(item))
            yield return inneritem;
}

If C# already had a yield from statement, this would be even shorter since you wouldn’t need to iterate the inner items explicitly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.