000170. Анонимные функции и лямбда-выражения в c#
Last updated
Last updated
Анонимные функции и лямбда-выражения в c#||wmysterio|wmysterio|wmysterio@yandex.ru|/||Всем привет! В этом уроке мы ещё раз поговорим о анонимности. На этот раз речь коснётся функций. Для того, чтобы статья лучше запомнилась, Вам необходимо повторить материал о делегатах и событиях. Поскольку делегат является ссылкой на метод, то мы можем использовать его для вызова анонимного метода. Анонимный метод - это функция, которая не имеет имени. Это даёт нам возможность писать функцию на ходу, без необходимости выносить её в область видимости экземпляра класса. Для более лучшего представления, давайте создадим проект Windows Forms, и кинем на форму две кнопки, которые будут иметь имена button1 и button2. Теперь нам нужно обработать события на нажатия кнопки, но делать мы будет на так, как мы рассматривали ранее в уроках. Будем учится писать анонимные функции! Для этого нажимаем правую кнопку мыши на визуальной форме и выбираем пункт "Перейти к коду". Далее подпишемся на событие Click для 1-й кнопки следующим образом:
Кодusing System.Windows.Forms; using System.Drawing; using System; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); button1.Click += delegate( object sender, EventArgs e) { MessageBox.Show( "Вы нажали на первую кнопку!" ); }; } } }Теперь, когда мы нажмём первую кнопку, то нам будет выводится сообщение о том, какая кнопка была нажата. С первого взгляда такая конструкция выглядит довольно громоздко, но это только так кажется при разработке Формы. Расскажу что к чему. Анонимный метод не имеет имени, по-этому имя заменяет ключевое слово delegate. В скобках указываются параметры с типами, которыми объявлен делегат. После этого в скобках пишется тело функции. Что касается лямбда-выражений, то это не так страшно, как при прочтении названия впервые. По-сути лямбда - это краткий вариант написания анонимных функций, за что разработчикам языка огромное спасибо!!! С первого вида конструкция лямбда выглядит ещё более запутанно и странно, чем обычный вид анонимных функций. Чтобы ознакомить Вас с синтаксисом, продемонстрирую вариант на другой кнопке формы:Кодusing System.Windows.Forms; using System.Drawing; using System; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); button2.Click += ( s, e ) => { MessageBox.Show( "Вы нажали на вторую кнопку!" ); }; } } }О ужас, скажет пользователь, который видит конструкцию в первый раз, так как синтаксически кажется, что там одни непонятные буквы и символы Но всему этому есть простое объяснение. Для начала рассмотрим синтаксис лямбды. Она состоит из двух частей(левой и правой), которые разделены символами =>. Левая часть в скобках перечисляет имена параметров, которые входят в лямбду. Имена могут быть произвольными, без указания их типов. Типы параметров берутся автоматически с сигнатуры делегата события, в данном случаи это object и EventArgs. Так что из важного в левой части лямбды - это указать требуемое количество параметров. Правая часть лямбда-выражения - это тело функции. Естественно код стал более компактным. Теперь поработаем с написанием своих делегатов и попытаемся использовать их в конструкторах. Чтобы не создавать новый проект, удалим из формы наши кнопки с реализацияей обработчиков событий а потом создадим класс Car, который будет у нас для экпериментов. Код класса:Кодnamespace WindowsFormsApplication1 { public class Car { public string Name { get; set; } public int MaxSpeed { get; set; } public Car() { Name = "Car"; MaxSpeed = 200; } } }Теперь давайте сделаем так, чтобы другой конструктор позволял нам выполнять пользовательскую функцию после инициализации переменных. Для этого создадим делегат с самой простой сигнатурой чуть выше тела класса:Кодpublic delegate void UserFunc(); // прототип пользовательской функцииДалее добавим ещё один конструктор:Кодnamespace WindowsFormsApplication1 { public delegate void UserFunc(); public class Car { public string Name { get; set; } public int MaxSpeed { get; set; } public Car() { Name = "Car"; MaxSpeed = 200; } public Car( UserFunc callback ) { Name = "Car"; MaxSpeed = 200; callback(); // вызываем переданную функцию } } }Как видим, в параметр конструктора мы должны передать объект типа UserFunc, который ссылается на функцию из вне класса, а затем вызываем её в конструкторе, как обычный метод. Таким образом мы реализовали имитацию колбэка. Остаётся только научится пользоваться этой возможностью! Давайте перейдём к код нашей формы и создадим три объекта класса Car, естественно с разными конструкторами. Во второй конструктор мы передадим анонимную функцию, которая будет изменять фон нашей формы, в третьем воспользуемся лямбда-выражением, который изменит заголовок формы:Кодusing System.Windows.Forms; using System.Drawing; using System; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); Car c1 = new Car(); // 1-й транспорт Car c2 = new Car( delegate() { BackColor = Color.Teal; ForeColor = Color.White; } ); // 2-й транспорт Car c3 = new Car( () => { Text = "Название изменил конструктор 3-его транспорта"; } ); // 3-й транспорт } } }При тестировании все задачи выполнились на ура, так что имитация удалась и мы передали функцию практически в другую функцию. Такой подход как правило ограничивается только делегатом, но креативные люди всегда смогут воспользоваться этим, для того, чтобы передавать в функцию любую функцию На этом всё. Надеюсь, информация была для Вас полезной.|1089|1|0||anonimnye_funkcii_i_ljambda_vyrazhenija_v_c|1426414316