Лямбда-выражения C#: почему я должен их использовать?



я быстро прочитал над Лямбда-Выражение Microsoft документация.



этот пример помог мне лучше понять, правда:



delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25


тем не менее, я не понимаю, почему это такое нововведение. Это просто метод, который умирает, когда" переменная метода " заканчивается, верно? Почему я должен использовать это вместо реального метода?

1089   14  

14 ответов:

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

ниже приведен пример LINQ to Objects выражение с использованием анонимных делегатов, а затем лямбда-выражения, чтобы показать, насколько легче на глаз они являются:

// anonymous delegate
var evens = Enumerable
                .Range(1, 100)
                .Where(delegate(int x) { return (x % 2) == 0; })
                .ToList();

// lambda expression
var evens = Enumerable
                .Range(1, 100)
                .Where(x => (x % 2) == 0)
                .ToList();

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

выражение деревьев являются очень мощной новой функцией C# 3.0, которая позволяет API смотреть на структуру выражения вместо того, чтобы просто получать ссылка на метод, который может быть выполнен. API просто должен сделать параметр делегата в Expression<T> параметр и компилятор будет генерировать дерево выражений из лямбды вместо анонимного делегата:

void Example(Predicate<int> aDelegate);

называется так:

Example(x => x > 5);

будет:

void Example(Expression<Predicate<int>> expressionTree);

последний получит переданное представление абстрактное синтаксическое дерево это описывает выражение x > 5. LINQ to SQL полагается на это поведение, чтобы иметь возможность включите выражения C# в SQL-выражения, необходимые для фильтрации / упорядочения / и т. д. на стороне сервера.

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

Рассмотрим пример:

 string person = people.Find(person => person.Contains("Joe"));

и

 public string FindPerson(string nameContains, List<string> persons)
 {
     foreach (string person in persons)
         if (person.Contains(nameContains))
             return person;
     return null;
 }

они функционально эквивалентны.

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

private ComboBox combo;
private Label label;

public CreateControls()
{
    combo = new ComboBox();
    label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);
}

void combo_SelectedIndexChanged(object sender, EventArgs e)
{
    label.Text = combo.SelectedValue;
}

благодаря лямбда-выражениям вы можете использовать его следующим образом:

public CreateControls()
{
    ComboBox combo = new ComboBox();
    Label label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += (s, e) => {label.Text = combo.SelectedValue;};
}

гораздо проще.

лямбда очистил синтаксис анонимного делегата C# 2.0...например

Strings.Find(s => s == "hello");

было сделано в C# 2.0 вроде этого:

Strings.Find(delegate(String s) { return s == "hello"; });

функционально, они делают то же самое, только гораздо более лаконичный синтаксис.

Это всего лишь один из способов использования лямбда-выражения. Вы можете использовать лямбда-выражение в любом месте вы можете использовать делегат. Это позволяет вам делать такие вещи:

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

strings.Find(s => s == "hello");

этот код будет искать в списке запись, которая соответствует слову "привет". Другой способ сделать это-фактически передать делегат методу Find, например:

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

private static bool FindHello(String s)
{
    return s == "hello";
}

strings.Find(FindHello);

EDIT:

В C# 2.0 это можно сделать с помощью анонимного делегата синтаксис:

  strings.Find(delegate(String s) { return s == "hello"; });

лямбда значительно очистил этот синтаксис.

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

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

и это не совсем новшество. LISP имеет лямбда-функции около 30 лет или больше.

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

delegate int MyDelagate (int i);
MyDelagate delSquareFunction = x => x * x;

рассмотрим лямбда-выражение x => x * x;

значение входного параметра равно x (слева от=>)

логика функции x * x (в правой части =>)

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

x => {return x * x;};

пример

Примечание: Func - это стандартный универсальный делегат.

    Console.WriteLine(MyMethod(x => "Hi " + x));

    public static string MyMethod(Func<string, string> strategy)
    {
        return strategy("Lijo").ToString();
    }

ссылки

  1. как делегат и интерфейс могут использоваться взаимозаменяемо?

вы также можете найти использование лямбда-выражений при написании общих кодов для действия на ваши методы.

например: универсальная функция для вычисления времени, затраченного на вызов метода. (т. е. Action здесь)

public static long Measure(Action action)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    action();
    sw.Stop();
    return sw.ElapsedMilliseconds;
}

и вы можете вызвать вышеуказанный метод, используя лямбда-выражение следующим образом,

var timeTaken = Measure(() => yourMethod(param));

выражение позволяет получить возвращаемое значение из вашего метода и из param, а также

var timeTaken = Measure(() => returnValue = yourMethod(param, out outParam));

много раз, вы используете только функциональность в одном месте, поэтому создание метода просто загромождает класс.

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

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

точно так же, почему вам нужно использовать foreach? Вы можете сделать все в foreach с помощью простого цикла for или просто используя IEnumerable напрямую. Ответ: вы не нужно но это делает ваш код более читабельным.

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

например, прежде чем вы могли бы использовать SQL и могли бы получить атаку SQL-инъекции, потому что хакер передал строку, где обычно ожидалось число. Теперь вы будете использовать лямбда-выражение LINQ, которое защищено от что.

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

в 2016 году большинство популярных языков лямбда-выражение поддержка и C# был одним из пионеров в этой эволюции среди основных императивных языках.

Это, пожалуй, лучшее объяснение того, почему использовать лямбда-выражения -> https://youtu.be/j9nj5dTo54Q

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

Comments

    Ничего не найдено.