Galin Iliev

Software Architecture & Development

Ламбда изрази

Ламбда изразите са естественото продължение на анонимните методи, които бяха въведени в 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 ламбда израз, който е извикван за всеки елемент от списъка. Като резултат в конзолата се отпечатват всички елементи на списъка.

Проекти с примерите

Проект за VS 2008 (5.87KB)

 

Следваща част: Дървета от изрази (Expression trees)

Content