Search code examples
c#genericsgeneric-type-argument

How to make SelectMany without argument work for generic IEnumerable<T>


I am trying to create a SelectMany() extension that can work without any query selector (so no argument at all). I have come up with the following:

public static IEnumerable<V> SelectMany<T, V>(this IEnumerable<T> enumerable) where T : IEnumerable<V> {
    return enumerable.SelectMany(e => e);
}

But the type arguments aren't recognized when I try to call it like this:

var d = new Dictionary<string, List<decimal>>();
var values = d.Values.SelectMany();

The type arguments for method 'CollectionsExtensions.SelectMany(IEmumerable' cannot be inferred from the usage. Try specifying the type arguments explicitly.

It only works with:

public static IEnumerable<V> SelectMany<K, V>(this Dictionary<K, List<V>>.ValueCollection enumerable) {
    return enumerable.SelectMany(e => e);
}

What am I missing?


Solution

  • The LINQ's SelectMany method expects a selector function that provides an IEnumerable<V> from an arbitrary object.

    You want your SelectMany method to process an IEnumerable<IEnumerable<V>> object instead, so there is no need to specify the selector function.

    So keep it simple:

    static IEnumerable<T> SelectMany<T>(this IEnumerable<IEnumerable<T>> enumerable)
        => enumerable.SelectMany(e => e);