Ламбда изрази
Ламбда изразите са естественото продължение на
анонимните методи, които бяха въведени в C# 2.0. За да проследим развитието ще започнем от самото начало като обясним
накартко делегатите.
Още с първата си версия C# предостави специален вид променлива, която сочи към методи –
делегатите. Това позволява делегати да се предават като параметри, да се
променят и да се извиква сочената функция. Използването на делегати позволява
елегантно промяна на програмния поток в зависимост от функциите, към които
сочат.
Делегати
В следващият пример са извършени следните операции:
·
Дефиниране на делегат Operation, който приема два параметъра.
·
Реализиран метод Multiply със същите параметри като делегата Operation.
·
В метода се създава променлива deleg, сочеща към инстанция на делегата Operation, която сочи към метода Multiply. Променливата deleg се извиква като нормален метод.
public delegate long Operation(long first, int second);
static long Multiply(long i, int j){
return i * j;
}
static void Main(string[] args){
Operation deleg = new Operation(Multiply);
long res =
deleg(12, 13);
}
|
Анонимни методи
С помощта на анонмните методи, които бяха
въведени в C# 2.0 горният код може да се съкрати до.
public delegate long Operation(long first, int second);
static void Main(string[] args){
deleg2 = (Operation)delegate(long i, int j) { return i * j; };
long res = deleg2(12, 13);
}
|
Разликата от предишният код е, че тук няма
метод Multiply, а е
осъществен без да е дадено изрично име на метода. Предимствата на анонимните
методи са:
·
Класът остава стегнат и не се разпокъсва от малки private методи.
·
Кодът се поставя там, където се използва вместо
някъде другаде в класа.
·
Не трябва да се измисля подходящо име на метода, но
трябва да се поставят подходящи коментари.
·
Не се указва тип на резултата – той се подразбира.
·
Може да се използват променливи от външният метод.
От анонимни методи към ламбда изрази
Ламбда изразите правят синтаксиса още по сбит.
Прототипът е следният:
(Списък
с параметри) => тяло на метода
|
Типът на параметрите не е задължителен и може
да се пропусне:
(x, string s) => s.Length > x
|
Ако тялото на метода съдържа повече от един
ред тогава цялото тяло се огражда с {}.
Използвайки лабда изразите горният пример
изглежда така:
static void Main(string[] args){
Operation deleg3 = (long i, int j) => {return i * j; };
long res =
deleg2(14, 13);
}
|
Правила за използване на ламбда изрази:
·
Скобите на списъка с параметри може да се пропусне,
ако параметъра е един - n => n<10, освен ако не се указва типа на параметрите – (string n) => n<10.
·
Скобите на списъка с параметри e задължителен ако параметрите са повече от един или няма входни
параметри.
·
Може да се достъпват променливи от външният метод
също като при анонимните методи.
Ламбда изразите са много често използвани в LINQ, както ще видим по късно в това ръководство. За да покажем силата на
тази конструкция ще разгледаме следният код:
List<int> numbers
= (new int[] { 1, 2, 3, 4, 5, 21, 22, 14, 16, 18 }).ToList<int>();
//print all
the numbers in the list to the console
numbers.ForEach(n
=> Console.WriteLine(n));
|
В първият ред инициализираме масив от
целочислени числа и го конвертираме към List<int>. На следващият ред
подаваме на разширяващият метод ForEach ламбда израз, който е извикван за всеки елемент от списъка. Като
резултат в конзолата се отпечатват всички елементи на списъка.
Следваща част: Дървета от изрази (Expression trees)