Kezdőlap > Uncategorized > Bevezetés a C# 3.0 újdonságaiba(3.) – Lambda kifejezések

Bevezetés a C# 3.0 újdonságaiba(3.) – Lambda kifejezések

Az egyik, talán első ránézésre legijesztőbb újdonság azok számára, akiknek a funkcionális programozás idegen, a C# 3.0-ban bevezetett lambda kifejezések. Segítségükkel kódot tudunk paraméterként átadni. Sokaknak biztos fel is sejlik a delegate-ek fogalma. Alapvetően egy sokkal kényelmesebb és érthetőbb szintaxis-t bocsátottak rendelkezésünkre, aminek segítségével névtelen függvényeket készíthetünk. Nézzük meg ugyanarra a feladatra, mindkét variációt:

Az első esetben a Where függvény paramétereként egy delegate-et(lényegében függvénypointert) adunk át és azt a kódot, amire mutat, rögtön definiáljuk is. Ugye ez a C# 2.0-ban bevezetett névtelen metódus. Ugye az történik, hogy minden listaelemre (adatbázisosan gondolkodva, "minden sorra") meghívjuk ezt a kódrészletet, ami akkor tér vissza igazzal, ha a szerző " John Steinbeck".

A második esetben lambda kifejezést használtunk. Azt mondtuk, hogy csak azok a "b"-k (Book példányok) érdekelnek, melyekre igaz az, hogy az "Author"-juk "John Steinbeck". Tehát a szintaxis lényegében a következő: paraméterek => kifejezés

Ami feltűnhet, hogy explicite nem adtuk meg "b" típusát. Ezt a fordító találta ki a Where bővítő metódus (későbbiekben részletesen) alapján. Természetesen explicite is meg lehet határozni a típust:

A fenti lambda kifejezés ún. predikátum, nem más, mint egy logikai kifejezés. Egy adott típusú paraméterre a visszatérési értek bool.

A projekció olyan lambda kifejezés, mely egy adott típusú paramétertől eltérő típust ad vissza, és nem logikai kifejezés.

A fenti példa összegzi a könyvek árait. A Sum függvénynek lambda kifejezés segítségével meghatároztuk, hogy a b példány Price változója alapján végezze el az szummázást.

A szokásos linq-s, sql-hez hasonló szintaxis, ilyen függvény hívásokba, a feltételek pedig lambda kifejezésekbe fordulnak. Sajnos ezt is nagyon jól kell ismernünk, ugyanis az szokásos sql-szerű szintaxisnak vannak korlátai, nem minden lehetőség érhető el benne.

Az alábbi kódrészlet ugyanazt a lekérdezést valósítja meg, az egyik sql-szerű szintaxissal (query expression), a másik lambda kifejezésekkel és bővítő függvényekkel (extension methods).

A lambda kifejezéseket váltózóknak értékül adhatjuk felhasználva a Func delegate típust.

Előre deklaráltak nekünk jó pár ilyen Func delegate típust, hogy lambda kifejezéseink kellően rugalmasak lehessenek.

A lambda kifejezések delegate-ként történő lefordítása és működése nagyon kényelmes, és kézenfekvő, ha memóriában lévő adathalmazokat szeretnénk lekérdezni (pl listák). De képzeljük el az a szituációt, amikor LINQ to SQL használatakor nagy adatbázisokból, nagy táblákból szeretnénk lekérdezni.

Fejeltsük most el a Book osztályunkat, és képzeljük el, hogy van egy nagy adatbázisunk, és az egyik táblája a "Books" nevet viseli. Gondoljunk bele, hogy mi lenne, ha előbb betöltené memóriába az adatokat, és aztán kezdené a lekérdezéseket végrehajtani. Amit várunk az az, hogy a linq to sql a lambda kifejezéseinket fordítsa SQL lekérdezésekbe, majd azt küldje át az adatbázisnak, így csak az eredmény jusson el hozzánk. Ezt úgy érhetjük el, hogy ha Func típusú delegate-ek helyett kifejezés fákat (expression tree) alkalmazunk.

Látható, hogy nem sima Func-ként, hanem Expression<Func…>-ként deklaráltam a változót. Így nem készül IL kód belőle fordítás időben, csak futásidőben, így ki lehet értékelni, ahogy csak szükséges. Természetesen, ezt a LINQ to SQL elvégzi helyettünk. Az alábbi ábrán látható, hogy a Where bővítő metódus itt most már Expression<Func<Product,bool>> típusú predikátumot vár.

Fontos megjegyezni, hogy az Expression-ként deklarált kifejezést nem lehet közvetlenül futtatni, ellentétben a Func típusú delegate-ként deklarálttal.

Nem szabad megijedni a lambdakifejezések használatától. Valójában egy nagyon jól használható, egyszerű dologról van szó, amit csak meg kell ismerni, rászánni egy órát és magunkévá tenni. Természetesen el lehet bonyolítani a végtelenségig, így akárcsak a többi újdonságot, ezt is használjuk óvatosan, hogy a kényelem ne menjen az olvashatóság, érthetőség kárára.

Kategóriák:Uncategorized
  1. Tibor
    január 11, 2008 - 1:09 du.

    Nagyon jok a cikkek szerintem, csak igy tovább:)várom a folytatást:)

  2. Zoltán
    január 11, 2008 - 5:13 du.

    Köszönöm, örülök, hogy tetszik! 🙂

  1. No trackbacks yet.

Hozzászólás