1
\$\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\$
3
  • 1
    \$\begingroup\$ You're doing this just as a learning exercise, right? Otherwise, reimplementing framework code doesn't make much sense. \$\endgroup\$
    – svick
    Commented Jul 25, 2012 at 10:35
  • \$\begingroup\$ Just to learn indeed. Fooling around with extension methods and delegates etc... :) \$\endgroup\$
    – HerbalMart
    Commented Jul 25, 2012 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
    Commented Jul 25, 2012 at 11:06

1 Answer 1

9
\$\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 and acknowledge you have read our privacy policy.

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