Два последовательных предложения from
переводятся с использованием метода расширения SelectMany
:
var occupiedSquares = squares
.SelectMany(s => pieces.Select(p => (s, p))) // Creates a ValueTuple
.Where(x => Occupies(x.p, x.s))
.Select(x => x.s);
Если вы работаете с более старой версией Framework, вы также можете использовать Анонимный тип вместо ValueTuple .
var occupiedSquares = squares
.SelectMany(s => pieces.Select(p => new { s, p }))
.Where(x => Occupies(x.p, x.s))
.Select(x => x.s);
Кроме того, вы также можете применить предложение Where к вложенному Select
. В этом случае не требуется агрегат (ValueTuple
или анонимный тип):
var occupiedSquares = squares
.SelectMany(
s => pieces
.Where(p => Occupies(p, s))
.Select(p => s)
);
Метод Enumerable.SelectMany обычно используется для выравнивания вложенной коллекции. Например, у вас есть список пользователей, а у пользовательских объектов есть список сообщений, и вам нужен список всех сообщений.
См. Также мой вопрос Вложенный запрос "from" LINQ, выраженный методами расширения и Эри c Липпертс ответ . (Eri c был частью команды C# Microsoft по компиляции.)