Как преобразовать запрос Linq-to-objects с двумя предложениями from в синтаксис метода - PullRequest
0 голосов
/ 16 марта 2020

Как преобразовать этот синтаксис запроса LINQ (это LINQ к объектам) в синтаксис метода:

var occupiedSquares = from s in squares
               from p in pieces
               where Occupies(p, s)
               select s;

(Occupies - это функция, возвращающая bool. Но обратите внимание, что квадрат не непосредственно содержит список занимающих фигур, и при этом часть не содержит непосредственно списка квадратов, которые она занимает. Синтаксис соединения, потому что нет общего ключа. (И работает ли метод Join даже при LINQ к объектам?).

1 Ответ

1 голос
/ 16 марта 2020

Два последовательных предложения 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 по компиляции.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...