Lambda kifejezések, LINQ Vegera József
Lambda kifejezés Névtelen metódus, amit delegáltak (vagy kifejezésfák) létrehozására használhatunk. Tartalmaz egy lambda operátort ( => ), ami elválasztja a metódus bemenő paramétereit a törzsétől. Általános külalakjuk: (bemenő paraméter/ek) => kifejezés Több kifejezésnél, vagy több végrehajtandó utasításnál tegyük őket { } közé!
Lambda példák delegáltakkal public delegate int Művelet(int x); … Művelet négyzet = (x) => (x * x); Console.WriteLine(négyzet(7)); --------------------------------------------------------------------------------------------------- public delegate bool LogDel(int x, int y); LogDel osztható = (x, y) => (x % y == 0); if(osztható(9,3)) Console.WriteLine("Maradék nélkül osztható.");
Void típusú példa public delegate void Kiír(string szöveg); static void Main(string[] args) { Kiír üzenet = (string szöveg) => Console.WriteLine("Üzenet:"); Console.WriteLine(szöveg); }; üzenet("Vegyél kenyeret!"); Console.ReadKey(); }
Lambda kifejezések generikus paraméterekkel Előzetes definiált delegate nélkül is megoldhatók az előző példák. Ilyenkor vagy Func, vagy Action típus használható, aszerint, hogy kell visszaadni eredményt (Func), vagy nem (Action). A Func esetében fel kell sorolni az összes bemenő paraméter típusát (jelenleg max. 16), utolsóként pedig a visszaadott típust: public delegate TResult Func<in T1, in T2, out TResult> ( T1 arg1, T2 arg2 ) public delegate void Action<in T1, in T2>
Előző példák generikusan Action<string>üzenet = (string szöveg) => { Console.WriteLine("Üzenet:"); Console.WriteLine(szöveg); }; üzenet("Vegyél kenyeret!");
Előző példák generikusan #2 Func<int, int, bool>osztható = (x, y) => (x % y == 0); if (osztható(9, 3)) Console.WriteLine("Maradék nélkül osztható.");
LINQ (Language Integrated Query) Különböző eredetű adatforrások egységes kezelése, feldolgozása Adatforrások lehetnek pl: XML SQL adatbázisok (elsősorban MsSQL) Objektumok, gyűjtemények a memóriában Egy LINQ lekérdezés részei: Adatforrás beállítása Lekérdezés készítése Futtatás és feldolgozás A lekérdezés típusa lehet: Query szintaxisú Lambda szintaxisú
LINQ Query példa A lekérdezés SQL-szerű szintakszist használ: int[] tömb = new int[8] { 0, 1, 2, 3, 4, 5, 6, 7 }; var lekérdezés = from x in tömb where (x % 2) == 0 select x; foreach (int szám in lekérdezés) { Console.Write(szám+ " "); }
LINQ Lambda példa Az előző példa Lambda típusú szintaxissal: int[] tömb = new int[8] { 0, 1, 2, 3, 4, 5, 6, 7 }; var lekérdezés = tömb.Where(x => x % 2 == 0); foreach (int szám in lekérdezés) { Console.Write(szám+ " "); }
LINQ lekérdezés felépítése A Query szintaxisú alak SQL utasításhoz hasonlít: var eredmény = from adat in adatok where adat.Átlag > 3 orderby adat.Név select adat; A from van elöl, hogy a többi részhez nyelvi támogatást kaphassunk. A „from adat in adatok” hasonló a „foreach adat in adatok”-hoz.
LINQ lekérdezések módosítása A lekérdezést zárójelbe téve további metódusokkal bővíthető, pl: Count Distinct First Take(n) Min, Max, Sum
Példák LINQ lekérdezésekre #1 Felhasznált adatszerkezet: struct Hallgató { //Tulajdonságok (auto-implementált) public string Név { get; set; } public double Átlag { get; set; } //Konstruktor public Hallgató(string név, double átlag) Név = név; Átlag = átlag; }
Példák LINQ lekérdezésekre #2 Adatok feltöltése: List<Hallgató> adatok = new List<Hallgató>(); adatok.Add(new Hallgató("Kovács Ádám", 3.2)); adatok.Add(new Hallgató("Szabó János", 4.9)); adatok.Add(new Hallgató("Takács Tímea", 2.3)); adatok.Add(new Hallgató("Balogh Edit", 3.7)); adatok.Add(new Hallgató("Balogh Ádám", 2.79));
Példák LINQ lekérdezésekre #3 #region A legjobb átlagú hallgató var eredmény2 = (from adat in adatok orderby adat.Átlag descending select adat).First(); //Ha nem a legelsőt, hanem az első néhányat szeretnénk, //használjuk a Take(n)-t!
Példák LINQ lekérdezésekre #4 #region A Balogh nevű hallgatók nevei var eredmény3 = (from adat in adatok where adat.Név.Contains("Balogh") select adat.Név);
Példák LINQ lekérdezésekre #5 #region Hallgatók csoportosítása betűrendben var eredmény4 = (from adat in adatok orderby adat.Név[0] group adat by adat.Név[0] into csoport select csoport);
Példák LINQ lekérdezésekre #5 foreach (var hallgatóCsoport in eredmény4) { Console.WriteLine(hallgatóCsoport.Key); foreach (var hallgató in hallgatóCsoport) Console.WriteLine("\t"+hallgató.Név); }
Teljes forráskód using System; using System.Collections.Generic; using System.Linq; namespace LINQ_példák { class Program struct Hallgató //Tulajdonságok (auto-implementált) public string Név { get; set; } public double Átlag { get; set; } //Konstruktor public Hallgató(string név, double átlag) Név = név; Átlag = átlag; } static void Main(string[] args) #region Adatok feltöltése List<Hallgató> adatok = new List<Hallgató>(); adatok.Add(new Hallgató("Kovács Ádám", 3.2)); adatok.Add(new Hallgató("Szabó János", 4.9)); adatok.Add(new Hallgató("Takács Tímea", 2.3)); adatok.Add(new Hallgató("Balogh Erzsébet", 3.7)); adatok.Add(new Hallgató("Balogh Ádám", 2.79)); #endregion #region A 3-nál jobb átlagúak névsor szerint var eredmény = from adat in adatok where adat.Átlag > 3 orderby adat.Név select adat; foreach (var hallgató in eredmény) Console.WriteLine(hallgató.Név + ", " + hallgató.Átlag); Console.WriteLine("----------------------------------"); #region A legjobb átlagú hallgató var eredmény2 = (from adat in adatok orderby adat.Átlag descending select adat).First(); //Ha nem a legelsőt, hanem az első néhányat szeretnénk, //használjuk a Take(n)-t! Console.WriteLine(eredmény2.Név + ", " + eredmény2.Átlag); #region A Balogh nevű hallgatók nevei var eredmény3 = (from adat in adatok where adat.Név.Contains("Balogh") select adat.Név); foreach(var név in eredmény3) Console.WriteLine(név); #region Hallgatók csoportosítása betűrendben var eredmény4 = (from adat in adatok orderby adat.Név[0] group adat by adat.Név[0] into csoport select csoport); foreach (var hallgatóCsoport in eredmény4) Console.WriteLine(hallgatóCsoport.Key); foreach (var hallgató in hallgatóCsoport) Console.WriteLine("\t"+hallgató.Név); Console.ReadKey();