Какой смысл в лямбда-выражении? - PullRequest
17 голосов
/ 03 мая 2011

После прочтения этой статьи я не могу понять, почему когда-либо используются лямбда-выражения. Честно говоря, я не думаю, что у меня есть правильное понимание того, что представляют собой делегаты и типы деревьев выражений, но я не понимаю, почему кто-то использует лямбда-выражение вместо объявленной функции. Может ли кто-нибудь просветить меня?

Ответы [ 7 ]

60 голосов
/ 03 мая 2011

Первый: краткость и локальность :

Что бы вы предпочли писать, читать и поддерживать?Это:

    var addresses = customers.Select(customer=>customer.Address);

или:

static private Address GetAddress(Customer customer)
{
     return customer.Address;
}

... a thousand lines later ...

    var addresses = customers.Select(GetAddress);

Какой смысл загромождать вашу программу сотнями или тысячами четырехстрочных функций, когда вы можете просто поместить нужный код где вам это нужно в качестве краткого выражения?

Секунда: лямбды закрываются над локальными областями

Что бы вы предпочли читать, писать и поддерживать, это:

var currentCity = GetCurrentCity();
var addresses = customers.Where(c=>c.City == currentCity).Select(c=>c.Address);

или:

static private Address GetAddress(Customer customer)
{
     return customer.Address;
}

private class CityGetter
{
    public string currentCity;
    public bool DoesCityMatch(Customer customer)
    {
        return customer.City == this.currentCity;
    }
}

....

var currentCityGetter = new CityGetter();
currentCityGetter.currentCity = GetCurrentCity();
var addresses = customers.Where(currentCityGetter.DoesCityMatch).Select(GetAddress);

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

Третье: Понимание запросов переписывается для вас в lambdas

Когда вы пишете:

var addresses = from customer in customers
                where customer.City == currentCity 
                select customer.Address;

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

Четвертый: лямбда-символы по выбору определяются

Примечаниечто нам не нужно указывать тип «customer» в понимании запросов выше или в лямбда-версиях, но мы должны указывать тип формального параметра при объявлении его как статического метода.Компилятор умеет выводить тип лямбда-параметра из контекста.Это делает ваш код менее избыточным и более понятным.

Пятый: Лямбды могут стать деревьями выражений

Предположим, вы хотите попросить веб-сервер «отправить мне адресаклиенты, которые живут в текущем городе. "Вы хотите (1) снять миллион клиентов с веб-сайта и выполнить фильтрацию на своем клиентском компьютере, или (2) отправить веб-сайту объект, который сообщает ему: «запрос содержит фильтр текущего города, а затемВыбор адреса "?Пусть сервер выполнит работу и отправит вам только соответствующий результат.

Деревья выражений позволяют компилятору преобразовывать лямбда-код в код, который может быть преобразован в другой формат запроса во время выполнения и отправлен на сервер для обработки.Маленькие вспомогательные методы, которые запускаются на клиенте, этого не делают.

5 голосов
/ 03 мая 2011

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

void Method(IEnumerable<Student> students, int age) {
  var filtered = students.Where(s => s.Age == age);
  ...
}

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

void Method(IEnumerable<Student> students, int age) {
  var c = new Closure() { Age = age };
  var filtered = students.Where(c.WhereDelegate);
  ...
}

class Closure {
  public int age;
  bool WhereDelegate(Student s) {
    return s.Age == age;
  }
}

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

4 голосов
/ 03 мая 2011

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

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

Более того, лямбда-выражения могут легко создавать замыкания (захватывать переменные из текущей области видимостии продлить свою жизнь).Это не волшебство (компилятор делает это, создавая скрытый класс и выполняя некоторые другие преобразования, которые вы можете сделать самостоятельно), но это намного удобнее , чем альтернатива вручную.

Кроме того, существуют деревья выражений: способ написать код и заставить компилятор преобразовать этот код в структуру данных, которую можно анализировать, изменять и даже компилировать во время выполнения.Это чрезвычайно мощная функция, которая открывает двери для впечатляющей функциональности (которую я определенно считаю LINQ).И вы получите это "бесплатно".

3 голосов
/ 03 мая 2011

http://msdn.microsoft.com/en-us/magazine/cc163362.aspx

Отличная статья о том, что такое лямбды и почему вы можете / должны их использовать.

По сути, лямбда-выражение обеспечивает сокращение для компилятораметоды и назначение их делегатам;это все сделано для вас.Преимущество, которое вы получаете с лямбда-выражением, которое вы не получаете от комбинации делегат / функция, состоит в том, что компилятор выполняет автоматический вывод типа для лямбда-аргументов

1 голос
/ 03 мая 2011

Они интенсивно используются с LINQ, на самом деле LINQ было бы довольно плохо без него. Вы можете сделать что-то вроде:

Database.Table.Where (t => t.Field == "Hello");

0 голосов
/ 28 ноября 2013

Лямбда делает код коротким и приятным. Рассмотрим следующие два примера:

ученик публичного класса

{


   public string Name { get; set; }
   public float grade { get; set; }
   public static void failed(List<Student> studentList, isFaild fail)
   {
       foreach (Student student in studentList)
       {
          if(fail(student))
          {
    Console.WriteLine("Sorry" + " "+student.Name + " "+  "you faild this exam!");
          }
       }
   }

публичный делегат bool isFaild (Student myStudent);

class Program
{
    static void Main(string[] args)
    {
        List<Student> studentsList  = new List<Student>();
        studentsList .Add(new Student { ID = 101, Name = "Rita", grade = 99 });
        studentsList .Add(new Student { ID = 102, Name = "Mark", grade = 48 });
        Student.failed(studentsList, std => std.grade < 60);  // with Lamda

          }
       }

приватный статический bool isFaildMethod (Student myStudent) // без лямбды

{

if (myStudent.grade <60) </p>

        {

            return true;

        }
        else
        {
            return false;
        }
    }
0 голосов
/ 03 мая 2011

Они позволяют легко передать часть функциональности другой функции. Например, я могу захотеть выполнить произвольную маленькую функцию для каждого элемента в списке (возможно, я хочу возвести его в квадрат, взять квадратный корень и т. Д.). Вместо того, чтобы писать новый цикл и функцию для каждой из этих ситуаций, я могу написать ее один раз и применить свою произвольную функциональность, определенную позже, к каждому элементу.

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