Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Различие анонимных методов и lambda

#c_sharp #lambda


В чем различие между анонимными методами и lambda-выражениями?
В анонимных методах мы можем обойтись без параметров, если даже это и ожидается:

public event EventHandler SomeEvent;
...
SomeEvent += delegate { Console.WriteLine("some information") };


Какие еще есть плюсы/минусу у анонимных методов и lambda-выражениями?
    


Ответы

Ответ 1



Разница в том, что лямбда, в зависимости от контекста использования, может быть скомпилирована в две совершенно разных вещи: Если контекст подразумевает использование лямбды как анонимного метода - лямбда компилируется в анонимный метод. Func filter = x => x > 2; будет превращено компилятором в то же, во что он превратит Func filter = delegate(int x) { return x > 2 }; Т.е. в этом варианте использования - лямбды - это просто сокращенный вариант старого синтаксиса анонимных методов. Именно в таком виде они внедрены в Java / C++ и остальных языках, которые "добавили лямбды" за последние пару лет. В той же Java лямбды - это единственный способ объявить анонимный метод. До введения лямбд в Java были анонимные классы (анонимные реализации интерфейсов), но не было анонимных методов - что сделало написание современного кода с промисами (аналогом Task) дико неудобным. Введение анонимных методов ("лямбд") значительно упростило написание цепочек тасков с коллбеками. В C# синтаксис анонимных методов был введен в 2.0, в 2005-ом году, цепочки промисов можно делать уже больше десяти лет, так что что лямбды в качестве альтернативного синтаксиса ключевому слову delegate картины не изменили. Вводились лямбды совсем не ради него. В этом варианте использования различия между лямбдами и delegate {} минимальны - на уровне "тут меньше скобок". Никаких принципиальных различий или значительных преимуществ между двумя синтаксисами нет. Если контекст подразумевает использование лямбды в виде значения типа Expression, то лямбда компилируется не в анонимный метод, а объект-композит, представляющий код лямбды в виде AST: Expression> filter = x => x > 2; превращается в ParameterExpression paramX = Expression.Parameter(typeof(int)); Expression> filter = Expression.Lambda>( Expression.GreaterThan( paramX, Expression.Constant(2) ), paramX ); Такое представление позволяет в рантайме преобразовывать выражения из кода (x > 2) в код на другом языке (SQL: WHERE table.ColumnX > 2, OData: $filter=x>2). Именно из-за этого варианта использования и ввели лямбды в C#, и именно за счет него работают LINQ-провайдеры вроде Entity Framework.

Комментариев нет:

Отправить комментарий