Вивчення лямбда-виразів в c # - все про it і програмуванні

Лямбда-вираз є вбудовуваним делегатом, введеним в мову C # 3.0. Це короткий уявлення безіменного методу. Він надає синтаксис для створення і виклику функцій. Хоча лямбда-вирази простіше використовувати, ніж безіменні методи, їх реалізація трохи відрізняється. І безіменні методи, і лямбда-вирази дозволяють визначати вбудовану реалізацію методу, однак безіменний метод явно вимагає визначати типи параметрів і тип повертається змінної для методу. Лямбда-вираз використовує можливість виведення типу C # 3.0, що дозволяє компілятору логічно виводити тип змінної на основі контексту.

Лямбда-вираз можна розділити на параметри з подальшим виконуваним кодом, наприклад:

Лямбда-вираз дозволяє передавати функції в якості аргументів викликом методу. Почнемо з простого прикладу лямбда-вирази, що повертає парні числа зі списку цілих чисел.

Поглянувши на перше лямбда-вираз, присвоєне змінної evens, ви помітите кілька відмінностей від безіменних методів. Перше - в коді ніде не використовується ключове слово delegate. Друге - не визначено типи параметрів і підлягає поверненню змінної, тому що компілятор логічно виводить тип на основі контексту. Типи в вираженні визначаються визначенням delegate. В даному випадку тип повертається змінної, заданий методом FindAll, приймає делегат, що приймає параметр int і повертає логічне значення. Лямбда-вираз без фігурних дужок і типу що повертається змінної є самим коротким способом подання безіменного методу. Якщо число параметрів дорівнює одиниці, то можна опустити круглі дужки, що оточують параметр, як показано в першому лямбда-виразі. Хоча лямбда-вираз не вимагає явних параметрів, можна визначити параметри, фігурні дужки і тип повертається змінної, як показано в другому лямбда-виразі, присвоєному змінної even2.

Використовується явний параметр int і тип повертається змінної, зазвичай задаються в методі. Оператор повернення не буде працювати, якщо не закрити виконуваний код круглими дужками, враховуючи, що ви повністю обумовили все, що відноситься до методу.

Інше місце, де потрібні круглі дужки в лямбда-виразі, - коли ви хочете використовувати параметр в декількох блоках коду всередині лямбда-вирази наступним чином:

Вивчення лямбда-виразів в c # - все про it і програмуванні

У прикладі коду вище код був укладений у фігурні дужки, щоб можна було використовувати параметр в обох висловах. Без фігурних дужок компілятор не зміг би розпізнати змінну i.

Можна використовувати лямбда-вирази, якщо делегат не має параметрів. В такому випадку треба задати пару порожніх круглих дужок, щоб позначити метод без параметрів. Нижче дан простий приклад, що показує лямбда без параметрів.

Вивчення лямбда-виразів в c # - все про it і програмуванні

C # 3.0 визначає кількість узагальнених делегатів, які можна призначити лямбда-виразу замість ключового слова var, логічно виводить тип. Розглянемо приклад використання декількох узагальнених делегатів:

В наведеному вище прикладі використовуються три різних розширюють методу: where, orderby і select. Розширює метод where приймає узагальнений делегат з параметром int і логічним типом повертається змінної, щоб визначити, чи буде конкретний елемент входити в вихідну послідовність. Розширює метод select приймає цілий параметр і повертає ціле число, але він може повернути все, у що ви хочете перетворити результат - перед відправкою в вихідну послідовність. У розширювальному методі orderby приймається цілий параметр і використовується для визначення його парності або непарності. На основі цього упорядковано результати. Це було б важко, якби довелося визначати три різних делегата для кожного лямбда-вирази. Завдяки введенню узагальнених делегатів в C # 3.0 вельми нетривіально призначати лямбда-вирази узагальненим делегатам і передавати ці делегати розширюють методам. Узагальнені делегати дуже зручні і допомагають уникнути написання спільних делегатів, які були поширені в .NET 1.1 і .NET 2.0 (так як не було готових узагальнених делегатів). Узагальнені делегати дозволяють визначати до 4 параметрів і 1 тип повертається змінної, тому використовуються такі делегати:

Якщо ваш метод або делегат не відповідає умовам, то вам доведеться вручну оголосити делегат, що приймає ці параметри. Узагальнені делегати зазвичай охоплюють більшість сценаріїв, але у випадках, коли він не задовольняє ваші потреби, пишіть призначений для користувача делегат.

Бувають випадки, коли виведення типу не повертає тип даних, який вам потрібно, щоб повертало лямбда-вираз. У таких випадках можна явно задати тип параметра в лямбда-виразі. наприклад:

Вираз вище повертає помилку компілятора, так як при розподілі double виведений тип насправді буде double. Однак ви призначаєте лямбда-вираз делегату, який має цілий тип повертається змінної. Якщо насправді ви хочете повертати int з методу, перетворіть тіло вираження в int, щоб вказати ваш намір, як показано нижче:

Лямбда-вирази бувають двох типів. Перший є простим вираженням, в якому все виводиться, і складається тільки з виразу. Другий тип лямбда-вирази є блоками операторів, що складаються з фігурних дужок і повертається типу. Напишемо лямбда-вираз в обох формах, щоб побачити різницю:

Підемо далі і розберемо кожне лямбда-вираз по черзі. Перше лямбда-вираз є простим вираженням, які не мають тіла оператора, так як немає оператора повернення і фігурних дужок, тоді як друге лямбда-вираз містить тіло оператора, так як має оператор повернення і фігурні дужки. Хоча обидва вирази компілюються в делегат, перевага лямбда-виразів без тіла оператора полягає в тому, що вони можуть бути перетворені в дерево виразів, яке конкретний постачальник може використовувати для генерації своєї власної реалізації. Подібно LINQ для SQL, це перетворює дерево виразів в його мову предметної області, іменований SQL, і відправляє його в базу даних. Третє лямбда-вираз показує відміну лямбда-вирази від безіменного методу. Краса цього оператора полягає в тому, що його легко перетворити в вираз, тоді як безіменний метод можна перетворити тільки в делегат. Прекрасно, що вираз можна перетворити назад в делегат шляхом компіляції вирази в делегат з допомогою наступного синтаксису:

Останнє лямбда-вираз генерує виняток, тому що компілятор не може перетворити лямбда-вираз, що містить тіло оператора, про що свідчить те, що воно оточене фігурними дужками і оператором повернення.

Хоча можна використовувати лямбда-вирази для генерації дерев виразів, ніщо не заважає вам прямо створити своє власне дерево виразів. Розберемо приклад створення дерева вирази для лямбда-вирази square = x => x * x.

Почнемо з виразу параметра типу int.

Наступний крок - створити тіло лямбда-вирази, що є двійковим виразом. Тіло складається з оператора множення для одного і того ж вирази параметра.

Заключний крок - створити лямбда-вираз, що з'єднує тіло з параметром наступним чином:

Останній крок перетворює вираз в делегат і виконує делегат наступним чином:

Створення вирази з іншого виразу

Можна взяти дерево вираження і змінити його, щоб створити інший вираз з нього. У наступному прикладі починаємо з лямбда-вирази x * x, потім міняємо цей вислів, додаючи до нього 2. Розглянемо приклад:

Починаємо з лямбда-вирази, що повертає square (квадрат):

Потім генеруємо тіло нового лямбда-вирази, використовуючи тіло першого лямбда-вирази і додаючи константу 2 до нього і призначаючи її допомогою бінарного висловом:

Замикання і лямбда-вирази

Замикання - концепція, взята з функціонального програмування. Воно захоплює або використовує змінну, що знаходиться поза області видимості лямбда-вирази. Це означає, що ви можете використовувати всередині лямбда-вирази змінні, оголошені поза області видимості лямбда-вирази - ви можете використовувати і захопити змінну, що знаходиться поза рамками лямбда-вирази. Це має свої плюси, але може викликати проблеми, тому що зовнішній контекст може змінювати значення змінної. Розберемо приклад лямбда-вирази з урахуванням замикання.

В наведеному вище прикладі використовується змінна mulitplyby всередині лямбда-вирази, хоча вона оголошена поза області видимості вираження. Такий принцип називається захопленням змінної. На задньому плані компілятор C # бере все захоплені змінні і поміщає їх в згенерований клас. При використанні лямбда-виразів з зовнішніми змінними, збирач сміття не збирає їх, і вони існують, поки не використовуються лямбда-виразами і вираз не покине зону видимості.

Є певні обмеження при використанні лямбда-виразів з параметром з ключовим словом ref і out. Якщо змінна передається з ключовим словом ref або out, треба явно задати тип параметра, тому що компілятор не може вивести тип змінної. Як показано в прикладі нижче:

Зверніть увагу, що в коді вище явно заданий тип параметра int в обох випадках, ref і out. Якщо опустити тип параметра, компілятор видасть помилку.

Інше обмеження при використанні лямбда полягає в тому, що не можна використовувати ключове слово params в типі параметра для лямбда-вирази, незалежно від того, заданий явно тип параметра чи ні. Наступний код не компілюється, тому що визначення параметра описано ключовим словом params:

В даній статті було розглянуто синтаксис лямбда-вирази - як воно замінює безіменний метод. Також сказано, що лямбда-вирази відрізняються від безіменних методів через виведення типів та їх здатності легко перетворюватися в делегати або дерева виразів. Були вивчені обмеження параметрів лямбда-виразів і то, як писати вираз з нуля і компілювати його в делегат, і навпаки.

• Приклади коду .NET по криптології [исходник - 38,5 КБ] [демо - 9.96 Кб] • Реалізація AES і DES на C # [исходник - 35,7 КБ] [демо - 13,1 КБ] 1. Введення Криптология - область, що займається забезпеченням безпеки та конфіденційності . Ця область включає в себе багато криптосистем, кажда.

Введення В даній статті пояснюються асинхронні виклики методів і принципи їх використання. Після роботи з делегатами, потоками і асинхронним викликом настала пора поділитися знаннями з цього питання. Використовуються маленькі кроки і безліч прикладів. Взагалі, буде показано, як викликати методи а.

Потрібно було створити кінцевий автомат для чинного продукту. Продукт був інструментом управління проектами і тому мав принцип завдання, заснований на переходах дій користувачів з одного стану в інший. Також потрібно, щоб кінцевий автомат можна було налаштовувати по / для різних.

Схожі статті