000170. Анонимные функции и лямбда-выражения в c#
Анонимные функци и и лямбда-выражения в c#||wmysterio|wmysterio|[email protected]|/||Всем привет! В этом уроке мы ещё раз поговорим о анонимности. На этот раз речь коснётся функций. Для того, чтобы статья лучше запомнилась, Вам необходимо повторить материал о делегатах и событиях. Поскольку делегат является ссылкой на метод, то мы можем использовать его для вызова анонимного метода. Анонимный метод - это функция, которая не имеет имени. Это даёт нам возможность писать функцию на ходу, без необходимости выносить её в область видимости экземпляра класса. Для более лучшего представления, давайте создадим проект 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


Last modified 1yr ago