Как работает это выражение LINQ? - PullRequest
5 голосов
/ 21 января 2010

Я знаю, что делает этот код, но я не уверен в синтаксисе. Кажется, он не соответствует «стандартному» формату. Это в основном LINQ?

return db.Subjects.SingleOrDefault(s => s.ID == ID);

Первая часть имеет смысл, но это часть в скобках, которую я не понимаю. Как мы можем использовать s без объявления этого? И как мы помещаем логику в вызов метода?

Ответы [ 6 ]

16 голосов
/ 21 января 2010

Первая часть имеет смысл, но это часть в скобках, которую я не понимаю.

Здесь вы видите лямбда-выражение . Это особенный анонимный делегат.

Это в основном LINQ?

Enumerable.SingleOrDefault - это метод LINQ, но лямбда-выражения не зависят от LINQ; они просто делают LINQ невероятно дружелюбнее, чем могло бы быть.

Теперь для получения конкретного IEnumerable<Subject>.SingleOrDefault(s => s.ID == ID) возвращает уникальный экземпляр Subject в IEnumerable<Subject>, который соответствует предикату s => s.ID == ID, или возвращает null, если такого экземпляра нет. Выдает исключение, если существует более одного такого экземпляра. Во время компиляции s => s.ID == ID преобразуется в полноценный делегат, который ест объекты типа Subject и возвращает bool, то есть true, если и только если s.ID равно ID.

Как мы можем использовать s без объявления этого?

=> - это лямбда-оператор . Это в основном отделяет левую часть лямбда-выражения от правой части. Слева - входные переменные. Это эквивалентно списку параметров в явно определенном методе. То есть s в лямбда-выражении играет роль s ниже:

public bool Predicate(Subject s)

Просто вам не нужно объявлять тип s, поскольку компилятор определит его.

Правая часть лямбда-тела. Это эквивалентно телу ниже

public bool Predicate(Subject s) {
    return s.ID == ID;
}

Более того, вам не нужно объявлять тип возвращаемого значения; компилятор выведет это к.

Итак, в конце концов, вы сделали следующее:

class MyPredicate {
    public string ID;
    public bool Predicate(Subject s) {
        return s.ID == this.ID;
    }
}

Тогда:

// elements is IEnumerable<Subject>
// ID is string
MyPredicate predicate = new MyPredicate();
predicate.ID = ID;
elements.SingleOrDefault(predicate.Predicate);

Приятно то, что компилятор просто автоматически выплевывает это для вас, когда вы используете лямбда-выражение.

5 голосов
/ 21 января 2010

Это компилятор C # 3.0, создающий для вас магию.

Это утверждение компилируется в делегат и эквивалентно:

return db.Subjects.SingleOrDefault(delegate(s) { return s.ID == ID }); 

Это называется лямбда-выражением, так как вам не нужно формально объявлять параметры, они выводятся компилятором C #.

5 голосов
/ 21 января 2010

Это называется лямбда-выражением. Смотрите здесь для объяснения. Лямбда-выражения (Руководство по программированию в C #)

4 голосов
/ 21 января 2010

Я думаю, что ваше замешательство связано с выражением s => s.ID== ID. Это лямбда-выражение. Проще говоря, это способ определения встроенной функции.

В этом случае текст слева от => является списком аргументов. Так что s объявляется в силу своего положения. Правая часть => является выполненным выражением. В этом конкретном контексте лямбда будет выполняться на каждом элементе коллекции, и код будет утверждать, что есть одно значение, которое соответствует выражению, выполняемому лямбда

0 голосов
/ 21 января 2010

s before => объявляет переменную с типом структурного элемента (тип содержится в переменной Subjects EDIT: другие функции работают с большим количеством аргументов, например, Join ), которая идет в правой части (after =>) , Логика исходит из функции. Если вы вызовете SingleOrDefault (поиск в документах), он вернет элемент SINGLE, если удовлетворяет условию или NULL. В LINQ есть много функций, которые вы можете использовать (т.е. First (), Where (), ...). Надеюсь, это поможет.

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