> For the complete documentation index, see [llms.txt](https://lessons.sannybuilder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lessons.sannybuilder.com/00300/00100/000170.-anonimnye-funkcii-i-lyambda-vyrazheniya-v-c.md).

# 000170. Анонимные функции и лямбда-выражения в c\#

Анонимные функции и лямбда-выражения в c#||wmysterio|wmysterio|<wmysterio@yandex.ru>|/||Всем привет! В этом уроке мы ещё раз поговорим о анонимности. На этот раз речь коснётся функций. Для того, чтобы статья лучше запомнилась, Вам необходимо повторить материал о [делегатах и событиях](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_iv/delegaty_i_sobytija_v_c/35-1-0-199/README.md). Поскольку делегат является ссылкой на метод, то мы можем использовать его для вызова анонимного метода. Анонимный метод - это функция, которая не имеет имени. Это даёт нам возможность писать функцию на ходу, без необходимости выносить её в область видимости экземпляра класса. Для более лучшего представления, давайте создадим проект **Windows Forms**, и кинем на форму две кнопки, которые будут иметь имена **button1** и **button2**. Теперь нам нужно обработать события на нажатия кнопки, но делать мы будет на так, как мы рассматривали ранее в уроках. Будем учится писать анонимные функции! Для этого нажимаем правую кнопку мыши на визуальной форме и выбираем пункт "Перейти к коду". Далее подпишемся на событие Click для 1-й кнопки следующим образом:

Кодusing System.Windows.Forms;\
using System.Drawing;\
using System;\
\
namespace WindowsFormsApplication1 {\
\
&#x20; public partial class Form1 : Form {\
\
&#x20; public Form1() {\
&#x20; InitializeComponent();\
&#x20; button1.Click += delegate( object sender, EventArgs e) { MessageBox.Show( "Вы нажали на первую кнопку!" ); };\
&#x20; }\
\
&#x20; }\
\
}Теперь, когда мы нажмём первую кнопку, то нам будет выводится сообщение о том, какая кнопка была нажата. С первого взгляда такая конструкция выглядит довольно громоздко, но это только так кажется при разработке Формы. Расскажу что к чему. Анонимный метод не имеет имени, по-этому имя заменяет ключевое слово **delegate**. В скобках указываются параметры с типами, которыми объявлен делегат. После этого в скобках пишется тело функции.\
\
Что касается лямбда-выражений, то это не так страшно, как при прочтении названия впервые. По-сути лямбда - это краткий вариант написания анонимных функций, за что разработчикам языка огромное спасибо!!! С первого вида конструкция лямбда выглядит ещё более запутанно и странно, чем обычный вид анонимных функций. Чтобы ознакомить Вас с синтаксисом, продемонстрирую вариант на другой кнопке формы:Кодusing System.Windows.Forms;\
using System.Drawing;\
using System;\
\
namespace WindowsFormsApplication1 {\
\
&#x20; public partial class Form1 : Form {\
\
&#x20; public Form1() {\
&#x20; InitializeComponent();\
&#x20; button2.Click += ( s, e ) => { MessageBox.Show( "Вы нажали на вторую кнопку!" ); };\
&#x20; }\
\
&#x20; }\
\
}О ужас, скажет пользователь, который видит конструкцию в первый раз, так как синтаксически кажется, что там одни непонятные буквы и символы ![smile](http://s49.ucoz.net/sm/15/smile.gif) Но всему этому есть простое объяснение. Для начала рассмотрим синтаксис лямбды. Она состоит из двух частей(левой и правой), которые разделены символами **=>**. Левая часть в скобках перечисляет имена параметров, которые входят в лямбду. Имена могут быть произвольными, без указания их типов. Типы параметров берутся автоматически с сигнатуры делегата события, в данном случаи это **object** и **EventArgs**. Так что из важного в левой части лямбды - это указать требуемое количество параметров. Правая часть лямбда-выражения - это тело функции. Естественно код стал более компактным.\
\
Теперь поработаем с написанием своих делегатов и попытаемся использовать их в конструкторах. Чтобы не создавать новый проект, удалим из формы наши кнопки с реализацияей обработчиков событий а потом создадим класс **Car**, который будет у нас для экпериментов. Код класса:Кодnamespace WindowsFormsApplication1 {\
&#x20;  \
&#x20; public class Car {\
\
&#x20; public string Name { get; set; }\
&#x20; public int MaxSpeed { get; set; }\
\
&#x20; public Car() {\
&#x20; Name = "Car";\
&#x20; MaxSpeed = 200;\
&#x20; }\
\
&#x20; }\
\
}Теперь давайте сделаем так, чтобы другой конструктор позволял нам выполнять пользовательскую функцию после инициализации переменных. Для этого создадим делегат с самой простой сигнатурой чуть выше тела класса:Кодpublic delegate void UserFunc(); // прототип пользовательской функцииДалее добавим ещё один конструктор:Кодnamespace WindowsFormsApplication1 {\
&#x20;  \
&#x20; public delegate void UserFunc();\
\
&#x20; public class Car {\
\
&#x20; public string Name { get; set; }\
&#x20; public int MaxSpeed { get; set; }\
\
&#x20; public Car() {  \
&#x20; Name = "Car";  \
&#x20; MaxSpeed = 200;  \
&#x20; }\
\
&#x20; public Car( UserFunc callback ) {\
&#x20; Name = "Car";\
&#x20; MaxSpeed = 200;\
&#x20; callback(); // вызываем переданную функцию\
&#x20; }\
\
&#x20; }\
\
}Как видим, в параметр конструктора мы должны передать объект типа UserFunc, который ссылается на функцию из вне класса, а затем вызываем её в конструкторе, как обычный метод. Таким образом мы реализовали имитацию колбэка. Остаётся только научится пользоваться этой возможностью! Давайте перейдём к код нашей формы и создадим три объекта класса **Car**, естественно с разными конструкторами. Во второй конструктор мы передадим анонимную функцию, которая будет изменять фон нашей формы, в третьем воспользуемся лямбда-выражением, который изменит заголовок формы:Кодusing System.Windows.Forms;\
using System.Drawing;\
using System;\
\
namespace WindowsFormsApplication1 {\
\
&#x20; public partial class Form1 : Form {\
\
&#x20; public Form1() {\
&#x20; InitializeComponent();\
\
&#x20; Car c1 = new Car(); // 1-й транспорт\
\
&#x20; Car c2 = new Car( delegate() {\
&#x20; BackColor = Color.Teal;  \
&#x20; ForeColor = Color.White;  \
&#x20; } ); // 2-й транспорт\
\
&#x20; Car c3 = new Car( () => {\
&#x20; Text = "Название изменил конструктор 3-его транспорта";  \
&#x20; } ); // 3-й транспорт\
\
&#x20; }\
\
&#x20; }\
\
}При тестировании все задачи выполнились на ура, так что имитация удалась и мы передали функцию практически в другую функцию. Такой подход как правило ограничивается только делегатом, но креативные люди всегда смогут воспользоваться этим, для того, чтобы передавать в функцию любую функцию ![smile](http://s49.ucoz.net/sm/15/smile.gif) На этом всё. Надеюсь, информация была для Вас полезной.|1089|1|0||anonimnye\_funkcii\_i\_ljambda\_vyrazhenija\_v\_c|1426414316
