23-04-21 1
Události (1)• Členy třídy umožňující objektu nebo třídě rea-
govat na zprávy (události)
• Dovolují třídě nebo objektu informovat jinou třídu nebo objekt, že nastala nějaká změna (událost)
• Třída, která:– zasílá (vyvolává) událost se označuje jako publi-
sher (vydavatel)– přijímá (obsluhuje) událost se nazývá subscriber
(odběratel)
23-04-21 2
Události (2)• Pro události platí:
– vydavatel udává, kdy událost nastane– odběratel stanovuje, jaká akce bude provedena jako
odpověď na vzniklou událost (jako obsluha udá-losti)– událost může mít více odběratelů– odběratel může obsloužit více událostí od různých
vydavatelů
• Bývají nejčastěji využívány v souvislosti s GUI k oznámení, že došlo k nějaké uživatelské akci (např. stisknutí tlačítka myši, výběr položky z menu apod.)
23-04-21 3
Události (3)• Program (třída) může definovat metody, které
mají za úkol zpracovat příchozí události
• Metoda realizující zpracování (obsluhu) udá-losti se označuje jako tzv. event handler (ob-služná metoda)
• Události jsou v jazyce C# implementovány pomocí delegátů
• Parametry obslužné metody musí odpovídat definici delegáta, jež definuje její signaturu
• Metod obsluhujících události může být více
23-04-21 4
Události (4)• Odkaz na obslužnou metodu se:
– do události vkládá pomocí operátoru +=– z události odebírá pomocí operátoru -=
• Události se definují pomocí klíčového slova event, za nímž následuje typ delegáta asocio-vaného s touto událostí a název události
• Příklad:public delegate void EventHandler(object sender, EventArgs e) public event EventHandler Click;
• Třídy, které chtějí na vzniklou událost reago-vat, musí delegáta tohoto typu vytvořit a aso-ciovat k němu obslužnou metodu
23-04-21 5
Události (5)• Konvence:
– delegát události by měl mít:• dva parametry:
– objekt, který událost vyvolal– parametr typu třída EventArgs (nebo typu třída, která je ze
třídy EventArgs odvozená), jež může specifikovat další infor-mace pro obslužnou metodu
• návratový typ void– obvykle se používá delegát EventHandler
• Před vyvoláním události by se vždy mělo ově-řit, zda člen události nenabývá hodnoty null tj. otestovat, zda událost má asociovánu obsluž-nou metodu
23-04-21 6
Události (6)• Poznámka:
– ke každé události bývá zvykem vytvořit chráněnou virtuální metodu (OnNázevUdálosti), která danou událost vyvolá
– příklad:protected virtual void OnClick (EventArgs e) {
EventHandler handler = Click; if (handler != null) handler(this,
e); }
– klíčové slovo protected označuje člena třídy, který je dostupný pouze v dané třídě a v třídách, které jsou z této třídy odvozené
23-04-21 7
Soubory a proudy (1)• Soubor (file) označuje pojmenovanou sadu dat
uloženou na externím záznamovém médiu (např. HDD, CD, DVD, BD, tape)
• Proud (stream) představuje „prostředníka“ mezi zdrojem, resp. příjemcem dat (např. soubor) a našim programem
• Knihovny dodávané s MS .NET Frameworkem poskytují abstraktní třídu Stream (definována ve jmenném prostoru System.IO), jež mimo jiné definuje abstraktní metody pro operace:– čtení z proudu – Read– zápis do proudu – Write– přesun v proudu – Seek
23-04-21 8
Soubory a proudy (2)• Skutečnost, zda daná operace je na konkrétním
proudu dostupná, lze ověřit pomocí vlastností CanRead, CanWrite a CanSeek
• V jazyku C# lze pracovat např. s proudy:– FileStream (System.IO):
• pro práci se soubory– MemoryStream (System.IO):
• pro práci s proudy uloženými v operační paměti – NetworkStream (System.Net.Sockets):
• pro komunikaci v prostředí počítačové sítě
• Poznámka:– výše uvedené proudy jsou definovány jako potomci
abstraktní třídy Stream
23-04-21 9
Třída FileStream (1)• Instance třídy FileStream se používají ke
čtení a k úpravám obsahu souboru• Při vytváření instance třídy FileStream je
možné konstruktoru předat např.:– název souboru (možno zadat včetně cesty)– informace o režimu otevření souboru (FileMode):
• např. vytvoření nového souboru, otevření existujícího souboru, přidávání dat na konec souboru
– informace o režimu přístupu (FileAccess):• soubor určený pro čtení, pro zápis nebo pro čtení i zápis
– informace o režimu sdílení (FileShare):• udávají, zda je soubor určený výlučně pro daný proud,
nebo jej současně mohou (pro specifikované operace) používat i jiné proudy
23-04-21 10
Třída FileStream (2)• Definuje např. vlastnosti:
– Length:• vrací počet bytů v proudu
– Position:• vrací nebo nastavuje aktuální pozici v proudu
• Načítání informací z proudu (souboru) se pro-vádí pomocí metody:int Read(byte[] a, int offset, int count)
• Metoda Read:– načítá do pole a od indexu offset nejvýše count bytů
– vrací počet načtených bytů (nebo nulu, jestliže bylo dosaženo konce proudu)
23-04-21 11
Třída FileStream (3)– posouvá současnou pozici v proudu za poslední
načtený byte• Zápis informací lze realizovat pomocí metodyvoid Write(byte[] a, int offset, int count)
• Metoda Write:– zapisuje do proudu z pole a od indexu offset count bytů
– posouvá současnou pozici v proudu za poslední zapsaný byte
• Pro načtení, resp. zápis jednoho bytu je možné použít metodu ReadByte, resp. WriteByte
23-04-21 12
Třída FileStream (4)• Pro nastavení aktuální pozice v proudu slouží
metodalong Seek(long offset, SeekOrigin origin)
• Parametr:– offset:
• udává relativní pozici vzhledem k hodnotě parametru origin
– origin: • specifikuje, zda pozice je vztažena k začátku, konci nebo
aktuální pozici v proudu
• Metoda Seek vrací novou pozici v proudu• Po dokončení práce se souborem by měl být
příslušný proud uzavřen
23-04-21 13
Třída FileStream (5)• Soubory lze uzavřít voláním metody Close• Metodu Close není nutné volat:
– stačí zajistit, aby každý proud byl korektně uvolněn– je zapotřebí, aby proud byl uzavřen za všech okol-
ností
• Za účelem uvolňování zdrojů existuje rozhraní IDisposable definující metodu Dispose, která příslušný zdroj uvolní
• Při práci se soubory by měly být použity bloky try a finally sloužící pro ošetření výjimek
23-04-21 14
Třída FileStream (6)• Příklad:FileStream fs; try {
fs = new FileStream(”data.txt”); fs.Write(…);} finally {
if (fs != null) fs.Dispose();
}
• Jazyk C# umožňuje zjednodušit použití rozhra-ní IDisposable pomocí klíčového slova using
23-04-21 15
Třída FileStream (7)• Příklad:using (FileStream fs = new FileStream(”data.txt”)) {
fs.Write(…);}
• Pro čtení (zápis) z (do) proudů je možné také využít třídy:– BinaryReader, BinaryWriter:
• pracují s otevřeným proudem (přístupným pomocí vlastnosti BaseStream) jako s binárním souborem
• dovolují číst (zapisovat) vestavěné datové typy– StreamReader, StreamWriter:
• pracují s otevřeným proudem (přístupným pomocí vlast-nosti BaseStream) na úrovni znaků textu v nějakém kódování (standardně UTF-8)
• umožňují s obsahem souboru pracovat jako s textem
23-04-21 16
Třída BinaryReader• Definována ve jmenném prostoru System.IO• Umožňuje načítání binárních hodnot• Pro vytvoření její instance je zapotřebí mít
otevřený proud• Poskytuje zejména metody pro načítání hodnot
vestavěných datových typů:– ReadBoolean, ReadByte, ReadChar, ReadDecimal, ReadDouble, ReadInt16, ReadInt32, ReadInt64, ReadSByte, ReadSingle, ReadString, ReadUInt16, ReadUInt32, ReadUInt64
• Po každém načtení se pozice v proudu posune za poslední načtený byte
23-04-21 17
Třída BinaryWriter• Definována ve jmenném prostoru System.IO
• Umožňuje zápis binárních hodnot• Pro vytvoření její instance je zapotřebí mít
otevřený proud• Obsahuje 18x přetíženou metodu Write pro
zápis různých vestavěných typů do proudu• Při každém zápisu se automaticky posouvá
pozice v proudu za poslední (zapsaný) byte• Změnu aktuální pozice v proudu je možné
provést i pomocí metody Seek
23-04-21 18
Třída StreamReader (1)• Definována ve jmenném prostoru System.IO• Potomek abstraktní třídy TextReader• Načítá znaky z proudu• Načítání je možné realizovat pomocí metody:
– int Read():• načítá z proudu jeden znak reprezentovaný jako Int32• posunuje pozici v proudu za načtený znak
– int ReadBlock(char[] buffer, int index, int count):
• načítá do pole buffer od indexu index nejvýše count znaků
• vrací počet načtených bytů• posunuje pozici v proudu za poslední načtený znak
23-04-21 19
Třída StreamReader (2)– string ReadLine():
• načítá z proudu řádek znaků a vrací jej jako řetězec
– string ReadToEnd():• načítá z proudu všechny znaky od aktuální pozice až do
jeho konce (vrací je jako řetězec)
23-04-21 20
Třída StreamWriter• Definována ve jmenném prostoru System.IO• Potomek abstraktní třídy TextWriter• Zapisuje znaky do proudu• Zapisování je možné realizovat pomocí přetíže-
ných metod:– Write():
• zapisují data různých datových typů (v závislosti na pře-tížené variantě) do proudu
– WriteLine():• zapisují data různých datových typů (v závislosti na pře-
tížené variantě) do proudu• za poslední zapsaný znak zapisují symbol konce řádku
23-04-21 21
Třídy StringReader a StringWriter
• Definovány ve jmenném prostoru System.IO• Třída:
– StringReader je potomkem třídy TextReader– StringWriter je potomkem třídy TextWriter
• Umožňují práci obdobným způsobem jako třídy StreamReader a StreamWriter
• Operace však neprobíhají nad proudy (soubory), ale nad řetězci
• Vhodné pro práci s textovými informacemi ulo-ženými v operační paměti
23-04-21 22
Manipulace se soubory• K provádění operací se soubory (vytváření, ko-
pírování, mazání, přesouvání, otevírání apod.) je možné využít třídy:– File (System.IO):
• statická třída, která definuje statické metody, např.:Copy, Create, Delete, Exists, GetAttributes, GetCreationTime, Move, Open, SetAttributes, SetCreationTime
– FileInfo (System.IO): • definuje:
– vlastnosti, např.: Attributes, CreationTime, DirectoryName, Exists, Extension, Length, Name
– instanční metody, např.:CopyTo, Create, Delete, MoveTo, Open
23-04-21 23
Manipulace s adresáři• K provádění operací s adresáři (vytváření, mazá-
ní, přesouvání, zjišťování souborů a podadresářů v adresáři apod.) je možné využít třídy:– Directory (System.IO):
• statická třída, která definuje statické metody, např.:CreateDirectory, Delete, Exists, GetCreationTime, GetCurrentDirectory, GetDirectories, GetFiles, GetLogicalDrives, Move, SetCreationTime, SetCurrentDirectory
– DirectoryInfo (System.IO):• definuje:
– vlastnosti, např.: Attributes, CreationTime, Exists, Extension, Name
– instanční metody, např.:Create, CreateSubDirectory, Delete, GetDirectories, GetFiles, MoveTo
23-04-21 24
Třída Path• Statická třída, která provádí operace nad řetězci,
jež obsahují informace o adresářových (soubo-rových) cestách
• Definuje statické metody, např.:– ChangeExtension: mění příponu – Combine: vytváří z pole řetězců cestu– GetExtension: vrací příponu– GetFileName: vrací jméno a příponu– GetFileNameWithoutExtension:
vrací jméno bez přípony– GetRandomFileName: vrací náhodné jméno
souboru nebo adresáře
23-04-21 25
LINQ (1)• LINQ (Language Integrated Query) je součást
MS .NET Frameworku umožňující jednotný přístup k datům a jejich zpracování deklarativ-ním a funkcionálním způsobem
• Představuje dotazovací jazyk (podobný SQL), který je integrovaný přímo do syntaxe jazyka C#
• Poskytuje syntaktickou kontrolu dotazů v době překladu programu
• Mezi výhody technologie LINQ patří zejména:– zjednodušení a zpřehlednění programového kódu– jednotná forma práce s různě reprezentovanými daty
23-04-21 26
LINQ (2)• LINQ:
– přináší nový způsob pro dotazování nad různě repre-zentovanými daty
– usnadňuje:• jejich třídění • jejich propojování • vyhledávání v nich
• Zpracovávaná data mohou být uložena např. v:– polích– kolekcích odvozených od generického rozhraní IEnumerable<T>
– XML– SQL databázích
23-04-21 27
LINQ (3)• Zpřehlednění práce s daty pomocí LINQ je v ja-
zyku C# dosaženo prostřednictvím:– implicitně typovaných proměnných (var)– rozšiřujících metod:
• metody rozšiřující již existující datové typy (třídy nebo struktury) dodatečnými statickými metodami
– lambda výrazů:• jednodušší forma zápisu anonymních metod
– inicializátorů objektů:• umožňují v době vytváření objektů nastavit jejich vlast-
nosti a datové položky (bez nutnosti použití specifického konstruktoru)
• příklad: Dog dog = new Dog { Name = ”Rex”, Age = 5 };
23-04-21 28
LINQ (4)– inicializátorů kolekcí:
• dovolují v době volání konstruktoru kolekce uvést seznam objektů
• kolekce musí implementovat rozhraní IEnumerable a obsahovat metodu Add pro vložení položky
• příklady:List<int> nums =
new List<int> { 1, 2, 3, 4, 5 };
List<Dog> dogs = new List<Dog>{ new Dog { Name = ”Rex”, Age = 5 }, new Dog { Name = ”Don”, Age = 2 }, new Dog { Name = ”Caesar”, Age = 7 }};
23-04-21 29
LINQ (5)– anonymních typů:
• slouží k zapouzdření proměnných bez nutnosti deklarovat datový typ
• obsahují jednu nebo více vlastností, které se nastaví při vytvoření instance a dále slouží jen ke čtení
• lze je deklarovat jen pomocí implicitně typované proměn-né (var)
• vlastnosti se určí z objektové inicializace• příklad: var Rex = new { Name = "Rex", Age = 5 };
• Překlad z dotazu LINQ na dotaz pro konkrétní platformu je realizovaný pomocí tzv. LINQ (po-skytovatelů) providers
23-04-21 30
LINQ (6)• Mezi nejčastěji používané poskytovatele techno-
logie LINQ patří:– LINQ to Objects:
• slouží k práci s libovolnou kolekcí (polem), která imple-mentuje rozhraní IEnumerable<T>
– LINQ to SQL:• mapuje příkazy LINQ na dotazy SQL a umožňuje práci
s MS SQL Server a MS SQL Express
– LINQ to DataSet:• používá technologii ADO.NET pro komunikaci s databá-
zemi
– LINQ to XML:• umožňuje práci se (dotazy nad) soubory XML
23-04-21 31
LINQ to Objects (1)• Definován ve jmenném prostoru System.Linq• Slouží k dotazování nad daty, která jsou v ope-
rační paměti (poli, třídami implementujícími rozhraní IEnumerable<T>)
• Dotazovací engine je spuštěn spolu s programem a umožňuje lokální dotazování
• Odpadává nutnost vytváření vlastních algoritmů pro vyhledávání v kolekcích
• Dotazování není dynamické:– jakmile se jeden dotaz vyhodnotí a vrátí výslednou
množinu, tak se do něj již nepromítají změny v pů-vodních datech
23-04-21 32
LINQ to Objects (2)• Pro zápis dotazů LINQ je možné použít např.
následující operátory (klíčová slova):– from:
• první klíčové slovo dotazu• slouží ke specifikaci datového zdroje, nad kterým je
prováděn dotaz– where (Where):
• umožňuje definovat podmínku (restrikci) pro výsledek• jestliže podmínka vrátí hodnotu true, tak je prvek
zahrnut do výsledku– select (Select):
• produkuje výsledky dotazu• používá se k implementaci projekce, kde jsou pouze něk-
teré datové složky objektu použity ve výsledku• uvádí se vždy na konci dotazu
23-04-21 33
LINQ to Objects (3)– group (GroupBy):
• umožňuje seskupování prvků ve výsledku podle určitého klíče
• k použití tohoto slova se váže také použití klíčového slo-va by
– into:• používáno v kombinaci s klíčovým slovem group, join nebo select k uložení výsledku a další možné práci s tímto výsledkem
– orderby (OrderBy, OrderByDescending):• slouží k řazení prvků ve výsledku podle definovaných
kritérií • pro sestupné řazení je možné jej použít s klíčovým
slovem descending
23-04-21 34
LINQ to Objects (4)– join (Join, GroupJoin):
• používá se k propojení prvků z různých datových zdrojů na základě definované podmínky ekvivalence
• v kombinaci s tímto slovem se používají nová slova equals a on
– let:• slouží k definici lokální proměnné v rámci dotazu• do této proměnné může být přiřazena sekvence elementů,
nebo jednoduchá hodnota
• Jmenný prostor System.Linq definuje ještě další rozšiřující metody, které lze v souvislosti s kolekcemi (poli) používat, např.:– First, Last:
• výběr prvního nebo posledního prvku
23-04-21 35
LINQ to Objects (5)– FirstOrDefault , LastOrDefault:
• vrací první, resp. poslední prvek• výchozí hodnotu daného datového typu v případě, že
dotaz vrátil prázdný výsledek– ElementAt:
• vrací prvek podle zadaného indexu– Count:
• vrací počet prvků– Union, Intersect, Except:
• provádí množinové operace (sjednocení, průnik a rozdíl)– Min, Max:
• vrací minimální, resp. maximální hodnotu– Sum, Average:
• vypočítá součet, resp. průměr prvků
23-04-21 36
LINQ to Objects (6)– Reverse:
• obrátí pořadí prvků v kolekci (poli)– Concat:
• spojí dvě sekvence (pole, kolekce) dohromady– OfType:
• výběr pouze těch prvků, které jsou specifikovaného typu– Take:
• vybere prvních n prvků– Skip:
• vybere všechny prvky počínaje (n+1). prvkem– TakeWhile:
• Vybírá prvky dokud není splněna určitá podmínka– SkipWhile:
• přeskakuje prvky, dokud není splněna určitá podmínka
23-04-21 37
LINQ to Objects (7)• Obecný tvar jednoduchého dotazu LINQ:from [typ] proměnná in datový_zdroj [where] podmínka_restrikce [orderby] klíč_řazení [descending] select výraz_projekce;
• Příklad:int[] numbers = { 1, 2, 3, 4, 5 };var result = from n in numbers where n < 4 orderby n descending select n;
vybere z pole numbers všechna čísla menší než 4 a provede jejich sestupné seřazení
23-04-21 38
LINQ to Objects (8)• Předcházející dotaz může být také zapsán s vy-
užitím rozšiřujících metod a lambda výrazů:int[] numbers = { 1, 2, 3, 4, 5 };var result = numbers.Where(n => n < 4). OrderByDescending(n => n);
• Dotazy LINQ jsou prováděny s tzv. odloženým spuštěním (deferred execution):– dotaz je spuštěn až ve chvíli, kdy je k němu přistou-
peno – samotné uložení dotazu do proměnné jeho spuštění
nevyvolá
23-04-21 39
LINQ to Objects (9)• Příklad:List<int> numbers = new List<int> {1, 2, 3, 4, 5}; var result = from n in numbers where n > 3 select n; numbers.Add(6); foreach (int i in result) Console.Write("{0} ", i);
• Uvedený program, vypíše hodnoty 4 5 6
23-04-21 40
Rozšiřující přednášky
• Datum: 10. 4. 2014
• Vyučující: Bc. Radim Göth
• Téma: Úvod do Entity Frameworku a ASP.NET MVC
• Datum: 17. 4. 2014
• Vyučující: David Kadlec
• Téma: Praktická ukázka ASP.NET Web Forms