# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lessons.sannybuilder.com/00300/00100/000170.-anonimnye-funkcii-i-lyambda-vyrazheniya-v-c.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
