Поиск…


замечания

Выражение лямбда является синтаксисом для создания анонимных функций inline. Более формально, из руководства по программированию на C # :

Выражение лямбда является анонимной функцией, которую можно использовать для создания делегатов или типов дерева выражений. Используя лямбда-выражения, вы можете записывать локальные функции, которые могут передаваться в качестве аргументов или возвращаться в качестве значений вызовов функций.

Выражение лямбда создается с помощью оператора => . Поместите любые параметры на левую сторону оператора. С правой стороны поставьте выражение, которое может использовать эти параметры; это выражение будет использоваться как возвращаемое значение функции. Реже, если необходимо, с правой стороны можно использовать целый {code block} . Если тип возврата не является недействительным, блок будет содержать оператор return.

Передача выражения Лямбды в качестве параметра метода

List<int> l2 = l1.FindAll(x => x > 6);

Здесь x => x > 6 - это лямбда-выражение, действующее как предикат, который гарантирует, что возвращаются только элементы выше 6.

Лямбда-выражения как сокращение для инициализации делегата

public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;

Вышеупомянутый синтаксис выражения Lambda эквивалентен следующему подробному коду:

public delegate int ModifyInt(int input);

ModifyInt multiplyByTwo = delegate(int x){
    return x * 2;
};

Lambdas для `Func` и` Action`

Обычно lambdas используются для определения простых функций (как правило, в контексте выражения linq):

var incremented = myEnumerable.Select(x => x + 1);

Здесь return неявно.

Тем не менее, также можно передавать действия как лямбда:

myObservable.Do(x => Console.WriteLine(x));

Лямбда-выражения с несколькими параметрами или без параметров

Используйте круглые скобки вокруг выражения слева от оператора => чтобы указать несколько параметров.

delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;

Аналогично, пустой набор круглых скобок указывает, что функция не принимает параметры.

delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";

Положить несколько выражений в заявление лямбда

В отличие от выражения lambda, оператор lambda может содержать несколько операторов, разделенных точкой с запятой.

delegate void ModifyInt(int input);

ModifyInt addOneAndTellMe = x =>
{
    int result = x + 1;
    Console.WriteLine(result);
};

Обратите внимание, что инструкции заключены в фигурные скобки {} .

Помните, что оператор lambdas не может использоваться для создания деревьев выражений.

Lambdas может излучаться как `Func`, так и` Expression`

Предполагая следующий класс Person :

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Следующая лямбда:

p => p.Age > 18

Может передаваться в качестве аргумента для обоих методов:

public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)

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

Очевидно, что провайдеры LINQ в значительной степени полагаются на Expression s ( IQueryable<T> основном через интерфейс IQueryable<T> ), чтобы иметь возможность анализировать запросы и переводить их для хранения запросов.

Выражение Lambda как обработчик события

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

  • Обработчик короток.
  • Обработчик никогда не должен быть отписано.

Ниже приведена хорошая ситуация, в которой может использоваться обработчик события лямбда:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");

Если необходимо отказаться от подписывания зарегистрированного обработчика событий в какой-то будущей точке кода, выражение обработчика события должно быть сохранено в переменной, а регистрация / регистрация осуществляется через эту переменную:

EventHandler handler = (sender, args) => Console.WriteLine("Email sent");

smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;

Причина, по которой это делается, а не просто повторное наложение выражения лямбда дословно, чтобы отменить подписку ( -= ), заключается в том, что компилятор C # не обязательно будет считать два выражения равными:

EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"

Обратите внимание, что если к выражению лямбда добавляются дополнительные операторы, тогда требуемые окружающие фигурные скобки могут быть случайно опущены, не вызывая ошибки времени компиляции. Например:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;

Это скомпилируется, но приведет к добавлению лямбда-выражения (sender, args) => Console.WriteLine("Email sent"); как обработчик события, и выполнение инструкции emailSendButton.Enabled = true; немедленно. Чтобы исправить это, содержимое лямбда должно быть окружено фигурными фигурными скобками. Этого можно избежать, используя фигурные скобки с самого начала, будучи осторожными при добавлении дополнительных инструкций в обработчик лямбда-события или окружающих лямбда в круглых скобках с самого начала:

smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//Adding an extra statement will result in a compile-time error


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow