Лямбда-выражения C#: почему я должен их использовать?
я быстро прочитал над Лямбда-Выражение Microsoft документация.
этот пример помог мне лучше понять, правда:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
тем не менее, я не понимаю, почему это такое нововведение. Это просто метод, который умирает, когда" переменная метода " заканчивается, верно? Почему я должен использовать это вместо реального метода?
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(); }ссылки
вы также можете найти использование лямбда-выражений при написании общих кодов для действия на ваши методы.
например: универсальная функция для вычисления времени, затраченного на вызов метода. (т. е.
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