Uplynulý týden jsem bohužel zcela neplánovaně strávil v laskavé péči zdravotnického personálu Nemocnice na Bulovce. Ve čtvrtek se sice stihl vydat naplánovaný první díl seriálu o genetických typech v C#, ale už jsem nebyl schopen k tomu nic napsat. Činím tak tedy alespoň teď, spolu s popisem nového dílu o cestě od delegátů k lambda expressions.
01 Generické typy
Generické typy jsou součástí jazyka C# už pěkně dlouho, konkrétně od verze 2.0, která vyšla někdy před šestnácti lety. Ve své podstatě se jedná o primitivní jazykovou funkci, která umožňuje tvorbu konstrukcí (metod, tříd...) které neberou argument jednoho konkrétního typu, ale jakéhokoliv typu T
. To umožňuje tvorbu velice elegantního a efektivního kódu, může zamezovat zbytečnému boxingu a unboxingu a přetypování.
Pomocí generických constraintů lze vlastnosti onoho typu T
přece jenom omezit. Například požadavkem aby měl bezparametrický konstruktor (pak lze vytvořit jeho novou instanci voláním new T()
, aby byl hodnotový, naopak referenční, nebo dědil od určité třídy či implementoval konkrétní interface a další.
02 Od delegátů k lambda expressions přes extension metody a yield return
Dnešní video pak představuje moje oblíbené demo, které dělám na každém druhém kurzu a kde si každý divák najde něco svého.
Jeho hlavním tématem je cesta C# od delegátů k lambda expressions. V úvodním dílu tohoto seriálu jsem zmínil, že C# dnes je jazykem multiparadigmatickým, že v něm lze programovat jak imperativně, tak funkcionálně. Typickou funkcionální konstrukcí je pak možnost předat kus programového kódu (třeba podmínku) jako argument nějaké metody, která se pak stane univerzálnější.
To C# umožňoval odjakživa v podobě dnes už poněkud pozapomenuté feature delegátů. Ale postupem času přibyla řada syntaktického cukru, která umožňovala ten předávaný kód zapisovat stále efektivněji a stručněji. Nejnovější evolucí jsou právě lambda expressions (poznáte je podle používaného symbolu =>
). Současný styl kódu počítá s jejich samozřejmou znalostí a využívá je velice extenzivně. Má zkušenost ale říká, že mnoho programátorů se v nich poněkud utápí. Moje video jim pomůže pochopit, jak vlastně vznikly a jak fungují.
Vedlejšími tématy tohoto videa jsou zajímavá konstrukce yield return
a pro úplnost se podíváme na extension metody, které umožňují rozšiřovat objekty o instanční metody, aniž by bylo nutné je modifikovat (nebo mít k modifikaci vůbec možnost).
Kombinace výše zmíněných technik pak vede k možnosti vytvoření technologie LINQ (Language Integrated Query), sloužící k dotazování do objektových datových struktur. V podobě LINQ to Enumerable jednoduše vykoná předaný kód jako argument, ale v pokročilejších variantách (jako je LINQ to entities) umí předanou lambda expression (resp. expression tree) nikoliv spustit, ale analyzovat a přeložit do jazyka úložiště (např. příslušného dialektu SQL), což umožňuje C# programátorům užívajícím Entity Framework psát komplexní dotazy, aniž by museli znát SQL nebo řešit rozdíly mezi jednotlivými relačními databázemi.
Zajímavé podrobnější informace o fungování delegátů v C# najdete v článku Understanding the cost of C# delegates od Paola Morgada.