400 likes | 701 Views
C# 3.0 és LINQ. Albert István. ialbert@aut.bme.hu. MSDN Kompetencia Központ. Budapesti Műszaki és Gazdaságtudományi Egyetem Automatizálási és Alkalmazott Informatikai Tanszék. Tartalom. C# 2.0 – rövid ismétlés Lambda kifejezések, automatikus tulajdonságok
E N D
C# 3.0 és LINQ Albert István ialbert@aut.bme.hu MSDN Kompetencia Központ Budapesti Műszaki és Gazdaságtudományi Egyetem Automatizálási és Alkalmazott Informatikai Tanszék Visual Studio "Orcas" Konferencia
Tartalom • C# 2.0 – rövid ismétlés • Lambda kifejezések, automatikus tulajdonságok • Bővítő metódusok, implicit típusú lokális változók • Objektum és gyűjtemény inicializálás • Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
A C# evolúciója C# 3.0 Nyelvbe ágyazott lekérdezések C# 2.0 • Típusbiztosabb, hatékonyabb nyelv • Generikus típusok, yield return C# 1.0 • Komponensek felügyelt környezetben • Property, delegate, event
demo Ismerős alapokGenerikus típusok • Típusbiztosabb, hatékonyabb gyűjtemények • Dobozolás nélkül • Típussal paraméterezett … • osztályok, interfészek, metódusok, delegate-ek • Típuskésznyerek a bővebb funkcionalitáshoz • Általánosabb, típusfüggetlenebbde továbbra is típusbiztos programozás • publicclassList<T> { • T[] array=newT[10];// tároló • publicvoidAdd( T item ) {this.array[count++] = item; }
demo Ismerős alapokSorozatok – IEnumerable<T> • Egyszerű sorozat (szekvencia) építés • Fordító trükk • Felfüggesztett végrehajtás - késleltett kiértékelés • (Speciális coroutine támogatás) public IEnumerable<T> Filter() { foreach( T tin this ) if( t.ToString().StartsWith("S" ) ) yield return t; } ... static void Main() { ... foreach( int i in list.Filter() ) Console.WriteLine( i ); }
demo Ismerős alapokNévtelen metódusok • Tipikus hivatkozás egyszer használatos kódra • Implementáció (kód) átadása metódusnak public IEnumerable<T> Filter( Predicate<T> filter ) { foreach( T tin this ) if( filter( t) ) yield return t; } ... static void Main() { ... foreach( int i in list .Filter( delegate( string s ) { return s.StartsWith( "S" ); } ) )Console.WriteLine( i ); }
Tartalom • C# 2.0 – rövid ismétlés Lambda kifejezések, automatikus tulajdonságok Bővítő metódusok, implicit típusú lokális változók • Objektum és gyűjtemény inicializálás • Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
demo Lambdakifejezések • Névtelen metódusok még rövidebb szintaktikával Ugyanaz mint: ‘s’ típusát kitalálja a környezetből ! • Több paraméter esetén a szintaktika • Paraméter nélkül is írható delegate( string s ) { return s.StartsWith( "S" ); } s => s.StartsWith( "S" ) ( x, y ) => Math.Sqrt( x * x + y * y ) () => 42
demo Automatikus tulajdonságokAutomatic properties private int <>field0; public intCount{ get { return <>field0; } private set {<>field0= value; } } • A hozzá tartozó mező nem érhető el • Get ÉS set is kell egyszerre ! • A láthatóság különbözhet • publicclassList<T> { • public intCount { get;private set; } • publicvoidAdd( T item ) • { this.array[Count++] = item; }
demo Bővítő metódusokExtension methods Statikus bővítő metódus • Meglévő osztály kiterjesztése • T lehet generikus osztály vagy interfész is • Mostantól minden sorozat szűrhető namespace linqSample.Utils{ public static class Helper { static public IEnumerable<T> Filter( this IEnumerable<T> seq, Predicate<T> filter ) { ... } A bővítendő típus a ‘this’ kulcsszó után A névtérben lévő összes bővítőmetódus engedélyezése using linqSample.Utils;
demo Implicit típusú lokális változókLocal Variable Type Inference • Nem kell kiírni a lokális változó típusát • A változó típusa a jobb oldali kifejezés típusa lesz • var == „a jobb oldal típusa” List<string> list= new List<string>(); foreach( string x in list.Filter( s => s.StartsWith("S") ) ) var list= new List<string>(); foreach(varx in list.Filter( s => s.StartsWith("S") ) )
Tartalom • C# 2.0 – rövid ismétlés • Lambda kifejezések, automatikus tulajdonságok • Bővítő metódusok, implicit típusú lokális változók Objektum és gyűjtemény inicializálás Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
demo Objektum inicializálókObject initializers • Objektumok inicializálása ha nincs megfelelő konstruktor • Mezők és tulajdonságok beállítása • Kifejezésben is használható var b=new Music{Title="Soul Bop",Length=591} var b0=new Music(); b0.Title="Soul Bop"; b0.Length=591; var b = b0; new Music { Title = "Soul Bop", Length =591 } . Dump(); list.Add( new Music { Title = "Soul Bop", Length =591 } );
demo Beágyazott tagokra is • Összetett típusú tagok inicializálása • Csak a tulajdonságok beállítása • Új objektum létrehozása értékadással new Music { Title = "Soul Bop", Length = 591, Album = { Artist = "Bill Evans", Year = 2000 } } new Music { Title = "Soul Bop", Length = 591, Album = new Album{ Artist = "Bill Evans", Year = 2000 } }
demo Gyűjtemények inicializálása • Hasonló a tömb inicializáláshoz • Publikus Add metódust hív • Több paraméteres Add metódust is támogat, pl: • Új implicit tömb inicializálás var list = new List<Music> { new Music { Title = "Soul Bop", Length = 591}, new Music { Title = "Hangin' in the City", Length = 397} }; varszamok = new Dictionary<int, string> { { 0, "nulla" }, { 1, "egy" }, { 2, "kettő" } }; var v = new [ ] { 1, 1.5, 2.3 };// double [ ]
demo Névtelen osztályok • Az osztály az inicializáláskor kapott tagokat kapja • Tulajdonságok • ToString(), Equals( object ), GetHashCode() • Azonos típus- és névsorrend ugyanazt a típust hivatkozza var list = new [ ] { new { Title = "Soul Bop", Length = 591}, new { Title = "Hangin' in the City", Length = 397} }; foreach( var x in list.Filter(s => s.Length < 300 ) ) Console.WriteLine( x );
Tartalom • C# 2.0 – rövid ismétlés • Lambda kifejezések, automatikus tulajdonságok • Bővítő metódusok, implicit típusú lokális változók • Objektum és gyűjtemény inicializálás • Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
demo Standard lekérdezések Standard Query Operators • Sorozatokon (sequence, IEnumerable<T>) működnek • A sorozat egyszerűen átalakítható: ToList(), ToArray(), ... • A System.Linq.Enumerable statikus osztály bővítő metódusaiból állnak • System.Core.dll, .NET 2.0-val is működik • Jellemzőik • Tipikusan késői kiértékeléssel dolgoznak (yield) • Kivételek, például Reverse(), OrderBy(), stb. • Összefűzhetőek, mégis hatékonyak • Megmarad a jó olvashatóság, komponálhatóság
demo A LINQ To Objects műveletei
Tartalom • C# 2.0 – rövid ismétlés • Lambda kifejezések, automatikus tulajdonságok • Bővítő metódusok, implicit típusú lokális változók • Objektum és gyűjtemény inicializálás • Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
demo LekérdezésekQuery Expressions • Lekérdezések nyelvi szinten (C# 3.0, VB 9.0) • A nyelvbe ágyazott lekérdezéseket metódushívásokká alakítja a fordító from m in list wherem.Title.StartsWith("S" ) select m. Title; list .Where( m => m. Title.StartsWith("S" ) ) .Select( m => m.Title);
A lekérdezések mintája from-mal kezdődik További from, join, let, where, vagyorderby fromidinsource { fromidinsource | joinidinsourceonexprequalsexpr [ intoid ] | letid = expr | wherecondition | orderbyordering, ordering, … } selectexpr | groupexprbykey [ intoidquery ] Végülselectbygroupby Opcionálisaninto-val folytatható
list cimek where select ID Length Title m=> m.Title.StartsWith("S”) m=> m.Title Késleltetett kiértékelés mégegyszerDeferred Query Execution var list = new List<Music> { ... }; varq = from m in list wherem.Title.StartsWith("S" )select m.Title; var q = list.Where( m => m.Title.StartsWith("S" ) ). Select( m => m.Title); q.ToList();
Tartalom • C# 2.0 – rövid ismétlés • Lambda kifejezések, automatikus tulajdonságok • Bővítő metódusok, implicit típusú lokális változók • Objektum és gyűjtemény inicializálás • Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
LINQ to ... from m in list wherem.Title.StartsWith("S" )select m.Title; • Mi kell ahhoz, hogy elvégezzük az átalakítást? • Leképezés: osztály – tábla, tag – oszlop, stb. • A szűrési feltétel eredeti, értelmezhető formában • Nem lefordítva IL kódra • Expression<T> : a kód adatként látszik • ahol T a kifejezésre jellemző metódusreferencia SELECT Title FROM Musicok WHERE Title LIKE ‘S%’
Kifejezés fák – kódból adatExpression Trees public delegate boolPredicate<T>(T obj ); Expression<Predicate<Music>> expr = m => m.Title.StartsWith("S" ); ParameterExpression p=Expression.Parameter(typeof(Music),"m"); expr=Expression.Lambda<Predicate<Music>>( Expression.Call( Expression.Property(p, GetMethod(Music.get_Title)), GetMethod(string.StartsWith), new Expression [] {Expression.Constant("S", typeof(string)) }), newParameterExpression [ ] { p });
Expression, Queryable, IQueryable • A Queryablehasonló az Enumerable-höz, de: • IQueryable<> interfész : IEnumerable<>, és: • Lehetővé teszi a kifejezések összefűzését is, például: • A Queryable osztály bővítő metódusai segítségével a teljes kifejezés eljut az adatforrásig (list, DataTable, stb.) • Végül a forrás alakítja át a kifejezést, például T-SQL-lé public staticIQueryable<TSource> Where <TSource>( thisIQueryable<TSource> source, Expression<Func<TSource, bool> > predicate); list . Where(…) . Take(…) . Select (…); // végül egy Expression lesz
demo LINQ to Desktop Search • OLEDB provideren keresztül, tipikus lekérdezés: • A Queryable . Where ( … ) átadja a szűrőt • Építjük és eltároljuk az egészet kifejezést • Enumerálásnál átalakítjuk WDS lekérdezéssé • Végrehajtjuk a lekérdezést OLEDB-n keresztül • Lezárjuk a kapcsolatot SELECT System.Title, System.Media.Duration FROMSystemIndex WHERE System.Title = 'Soul Bop'
demo Egy kifejezés fa, bejárása newWDS() . Where( m => m.Title.StartsWith( "S" ) && m.Length > 300 ); MethodCallWhere … WHERE System.TitleLIKE 'S%’ AND ….Duration > 300 Object (root) WDS LambdaExp m => … AndAlso … && … MethodCall ….StartsWith( … ) GreaterThan … > … MemberAccess m.Title Constant “S” MemberAccess m.Length Constant 300
LINQ architektúra from m in list wherem.Title.StartsWith("S" )select m.Title; var q = list.Where( m => m.Title.StartsWith("S" ) ). Select( m => m.Title); A forrás IEnumerable<T> A forrás IQueryable<T> System.Linq.Enumerabledelegate alapú System.Linq.Queryablekifejezésfa alapú Objektumok SQL DataSet Egyéb...
Tartalom • C# 2.0 – rövid ismétlés • Lambda kifejezések, automatikus tulajdonságok • Bővítő metódusok, implicit típusú lokális változók • Objektum és gyűjtemény inicializálás • Névtelen típusok • Standard lekérdezések, LINQ to Objects • Nyelvbe ágyazott lekérdezések • Kifejezés fák • Összefoglalás
Lekérdezések C# 3.0 var q = from m in list wherem.Title.StartsWith("S" ) select new {m.Title, m.Length }; Implicit típusú lokális változó Lambda kifejezések var q = list .Where( m => m.Length.StartsWith("S" ) ) .Select( m => new { m.Title, m.Length } ); Objektum inicializálók Névtelen típusok Bővítő metódusok
A másfajta megközelítés előnyei • Bizonyos feladatoknál kisebb hiba százalék • Tömörebb kód • DE csak addig tömörítsük, amíg ... • Jobban átlátható, karbantartható • Néha párhuzamosítható • Akár keretrendszer szinten (PLINQ) • Nyelvi szintű integráció más területekkel • Relációs adatok, XML, AD, ...
<book> <title/> <author/> <year/> <price/> </book> Relációs adatbázisok Objektumok XML A LINQ projekt C# 3.0 VB 9.0 más nyelvek… .NET Language Integrated Query LINQ toObjects LINQ toDataSets LINQ toSQL LINQ toEntities LINQ toXML
A .NET 3.5 és a jövő • LINQ to Objects: ez volt most • LINQ to XML: jön a szünet után • LINQ in Visual Basic: még egy óra • LINQ to DataSet: még ebéd előtt • LINQ to SQL: ebéd után • LINQ to Entities: mielőtt haza mennénk • LINQ to SharePoint: ... • LINQ to LDAP (Active Directory): ... • LINQ to WMI: … • Paralell LINQ: egy év múlva (?)
Összefoglalás • Nem kell használni • De már most is lehet a .NET 2.0-ban VS 2005-tel • Úgy nőtt az absztrakciós szint, hogy ‘megmaradt az alja’ • Apró lépések a nyelvben • yield return, extension methods, lambda expr., var, stb. • Néhány osztály a Framework-ben • System.Linq.Enumerable (.Where, .OrderBy, ...) • Egy kis transzformáció • from x in ... where ... select ... • A mennyiség végül új minőséggé válik (G. Kasparov)
További információk • Fejlesztői Portál – devPORTAL{..} • http://www.devportal.hu • LINQ Project honlap • http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx • 101 LINQ Samples • http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx • LINQ Project Forum • http://forums.microsoft.com/msdn/showforum.aspx?forumid=123&siteid=1 • AndersHejlsberg interjú a LINQ-ről • http://channel9.msdn.com/showpost.aspx?postid=114680 • Visual Studio Code Name „Orcas” letöltések • http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx
Kérdések és válaszok Kérjük írja meg részletes véleményét az előadással kapcsolatban az értékelőlapon!
QuicksortC# 3.0-ban típussal paraméterezett funkció Func<intlist, intlist> Sort = xs => xs.Case( () => xs, (head,tail) => (Sort(tail.Where(x => x < head))) .Concat (Single(head)) .Concat(Sort(tail.Where(x => x >= head))) ); magasabb rendű funkció lambda kifejezés összefűzés type inference szűrés rekurzió
© 2007Microsoft Corporation. Minden jog fenntartva. Az előadás csupán tájékoztató jellegű, a Microsoft Magyarország a benne szereplő esetleges hibákért vagy tévedésekért semmilyen felelősséget nem vállal.