Во-первых, вам не нужно Flatten()
;этот метод уже существует и называется SelectMany()
.Вы можете использовать его следующим образом:
IEnumerable<IEnumerable<int>> foo = new [] { new[] {1, 2}, new[] {3, 4} };
var bar = foo.SelectMany(x => x); // bar is {1, 2, 3, 4}
Во-вторых, ваша первая попытка не работает, потому что вывод универсального типа работает только на основе аргументов метода, а не общих ограничений, связанных с методом.Поскольку нет аргумента, который напрямую использует универсальный параметр J
, механизм вывода типов не может угадать, каким должен быть J
, и поэтому не считает, что ваш метод является кандидатом.
Этоназидательно, чтобы увидеть, как SelectMany()
справляется с этим: для этого требуется дополнительный аргумент Func<TSource, TResult>
.Это позволяет механизму вывода типов определять оба универсальных типа, поскольку они оба доступны только на основе аргументов, предоставленных методу.