12/04/20151 Kolekce (1) Kolekce (collection) představují standardní datové struktury (seskupení) prvků (objektů) Jsou definovány ve jmenném prostoru System.Collections a jmenných pros- torech do něj vnořených Na rozdíl od polí se jejich velikost v průběhu programu může dynamicky zvětšovat, resp. zmenšovat Některé kolekce umožňují ukládaným objek- tům přiřadit klíč, pomocí něhož lze daný objekt rychle zpřístupnit
12/04/20152 Kolekce (2) Jazyk C# rozlišuje kolekce: –negenerické, obecné (non-generic): třídy, které implementují rozhraní IEnumerable ukládají data typu object po získání prvku z kolekce bývá nutné provést jeho přetypování nejsou typově bezpečné v současné době nejsou příliš používány zůstávají zachovány zejména z důvodu zpětné kompa- tibility příklady: ArrayList, Stack, SortedList, Queue
12/04/20153 Kolekce (3) –generické (generic): třídy, které implementují rozhraní IEnumerable a IEnumerable ( IEnumerable dědí od rozhraní IEnumerable ) dovolují specifikovat datový typ ukládaných prvků ve chvíli vytvoření instance reprezentují silně typované (typově bezpečné) kolekce příklady: Collection, List, HashSet, Stack, Queue, Dictionary Rozhraní IEnumerable, resp. rozhraní IEnumerable definují metodu GetEnumerator
12/04/20154 Kolekce (4) Metoda GetEnumerator vrací objekt Enumerator, resp. Enumerator do- volující snadné procházení kolekcí pomocí příkazu foreach Použití foreach je umožněno tím, že objekt Enumerator, resp. Enumerator implementuje rozhraní IEnumerator, resp. IEnumerator, které definuje: object Current { get; } bool MoveNext(); void Reset(); T Current { get; } bool MoveNext(); void Reset();
12/04/20155 Kolekce (5) Vlastnost: –Current : slouží pro načtení prvku na aktuální pozici enumerátoru Metody: –MoveNext : posune enumerátor na další prvek v kolekci –Reset : nastaví enumerátor na iniciální pozici, tj, před první prvek v kolekci
12/04/20156 Třída Collection Definována ve jmenném prostoru: System.Collections.ObjectModel Její instance podporují přístup k jednotlivým prvkům prostřednictvím indexu Počet ukládaných prvků není nijak limitován Není určena pro běžné použití Představuje základní třídu pro generické ko- lekce Slouží zejména jako třída pro tvorbu vlastních kolekcí
12/04/20157 Třída List (1) Definována ve jmenném prostoru: System.Collections.Generic Reprezentuje silně typovaný seznam objektů, které mohou být zpřístupněny pomocí indexu Prvky jsou ukládány pomocí pole, jehož veli- kost se dynamicky zvětšuje Počet prvků v seznamu je dán hodnotou vlast- nosti Count Třída List poskytuje např. metody: –void Add(T item) : přidá prvek item na konec seznamu – O(1), O(n)
12/04/20158 Třída List (2) –void Clear() : odstraní všechny prvky ze seznamu – O(n) –bool Contains(T item) : zjišťuje, zda se v seznamu nachází prvek item – O(n) –int IndexOf(T item) : hledá (lineárně) první výskyt prvku item – O(n) –void Insert(int index, T item) : vloží do seznamu prvek item na pozici index – O(n) –bool Remove(T item) : odebere ze seznamu první výskyt prvku item – O(n) –void RemoveAt(int index) : odebere ze seznamu prvek na pozici index – O(n)
12/04/20159 Třída List (3) –void Sort() : seřadí prvky seznamu (QuickSort) – O(n.log(n)), O(n 2 ) –void Reverse() : obrátí pořadí prvků v seznamu – O(n) –int BinarySearch(T item) : hledá v seznamu prvek item metodou půlení interva- lu – O(log(n)) prvky musí být nejprve seřazeny –T[] ToArray() : kopíruje prvky seznamu do pole – O(n) Poznámka: –třída List představuje generický ekvivalent negenerické třídy ArrayList
12/04/ Třída Dictionary (1) Definována ve jmenném prostoru: System.Collections.Generic Reprezentuje kolekci (slovník) klíčů a hodnot Každý klíč: –je asociovaný s odpovídající hodnotou –musí být jedinečný Poskytuje mapování z množiny klíčů na mno- žinu hodnot – klíče mohou být použity jako index pro zpřístupnění hodnoty Při přidávání prvků se automaticky alokuje další potřebné paměťové místo
12/04/ Třída Dictionary (2) Implementována jako hashovací tabulka Počet dvojic klíč, hodnota je dán hodnotou vlastnosti Count Třída Dictionary poskytuje např. metody: –void Add(TK key, TV value) : přidá dvojici klíč, hodnota do slovníku – O(1), O(n) –bool ContainsKey(TK key) : zjišťuje, zda slovník obsahuje klíč key – O(1) –bool ContainsValue(TV value) : zjišťuje, zda slovník obsahuje hodnotu value – O(n)
12/04/ Třída Dictionary (3) –void Clear() : odstraní ze slovníku všechny klíče a hodnoty – O(n) –bool Remove(TK key) : odebere ze slovníku hodnotu s klíčem key – O(1) –bool TryGetValue (TK key, out TV value) : zpřístupňuje hodnotu value se specifikovaným klíčem key – O(1)
12/04/ Třída HashSet (1) Definována ve jmenném prostoru: System.Collections.Generic Reprezentuje množinu hodnot Umožňuje provádět množinové operace Nemohou se v ní vyskytovat duplicitní hod- noty Při přidávání prvků se automaticky alokuje další potřebné paměťové místo Počet prvků množiny je obsažen ve vlastnosti Count
12/04/ Třída HashSet (2) Implementována pomocí hashovacího algorit- mu Třída HashSet poskytuje např. metody: –bool Add(T item) : přidá prvek item do množiny – O(1), O(n) –void Clear() : odebere všechny prvky z množiny – O(n) –bool Contains(T item) : zjišťuje, zda množina obsahuje prvek item – O(1) –void CopyTo(T[] array) : kopíruje prvky množiny do pole array – O(n)
12/04/ Třída HashSet (3) –void ExceptWith(IEnumerable c) : odebere z množiny prvky specifikované kolekcí c – O(n) –void IntersectWith(IEnumerable c) : provede průnik množiny a kolekce prvků c – O(n) –bool IsSubsetOf(IEnumerable c) : testuje, zda množina je podmnožinou kolekce c – O(n) –bool IsSupersetOf(IEnumerable c) : testuje, zda množina je nadmnožinou kolekce c – O(n) –bool Remove(T item) : odebere z množiny prvek item – O(1) –bool UnionWith(IEnumerable c) : provede sjednocení množiny a kolekce prvků c – O(n)
12/04/ Srovnání kolekcí List Dictionary HashSet Vyhledávání prvku Vložení prvku Smazání prvku Hodnota: O(n) O(log(n)) Index: O(1) Hodnota: O(n) Klíč: O(1) O(1), O(n) O(n) O(1)
12/04/ Iterátory (1) Iterátor je blok příkazů (metoda, přístupová metoda get ), který poskytuje uspořádanou sekvenci hodnot Obsahuje vždy alespoň jeden příkaz yield : –yield return výraz; : produkuje další hodnotu iterace (dána výsledkem výra- zu za klíčovým slovem return ) –yield break; : ukončuje iteraci (oznamuje, že není dostupná žádná další hodnota)
12/04/ Iterátory (2) Návratovým typem metody představující iterá- tor musí být: –IEnumerator, IEnumerator –IEnumerable, IEnumerable Hodnoty poskytované iterátorem mohou být zpřístupňovány pomocí příkazu foreach : –každá iterace cyklu foreach volá metodu iterátoru –po provedení příkazu yield return dojde k vrá- cení hodnoty –zůstává zachováno místo, kde byla metoda opuštěna –při dalším volání se pokračuje od místa předešlého opuštění metody
12/04/ Iterátory (3) Příklad: public static IEnumerable OddNums(int n) { int i = –1; while (i < n – 1) { i += 2; yield return i; } } static void Main(string[] args) { foreach (int i in OddNums(10)) Console.Write("{0} ", i); Console.WriteLine(); }
12/04/ Delegáty (1) Delegát (delegate) je datový typ, který definuje signaturu metody Delegáty bývají rovněž označovány jako typo- vě bezpečné ukazatele na funkce Deklarace delegáta definuje třídu, jež je odvo- zena z třídy System.Delegate Instance delegáta: –slouží k reprezentaci odkazu (reference) na metodu (instanční i statickou) –může být asociována s libovolnou metodou, která má kompatibilní signaturu (stejný návratový typ a stejné parametry)
12/04/ Delegáty (2) Umožňují předávat metody jako parametry ji- ným metodám Delegát se deklaruje s: –použitím klíčového slova delegate –popisem návratového typu –popisem parametrů Příklad: public delegate int BinOpDel(int op1, int op2); Před použitím delegáta je zapotřebí vytvořit jeho instanci, čímž dojde k asociování s kon- krétní metodou
12/04/ Delegáty (3) Poznámka: –jazyk C# také povoluje přiřadit do delegáta pouze název metody Příklad: public static int Add(int op1, int op2) { return op1 + op2; } static void Main() { BinOpDel delVar = new BinOpDel(Add); // BinOpDel delVar = Add; int sum = delVar(1, 2); Console.WriteLine(sum); }
12/04/ Delegáty (4) Není-li delegátu přiřazena žádná hodnota (tzv. prázdný delegát), pak má hodnotu null Vyvolání prázdného delegáta způsobí výjimku NullReferenceException Při práci s delegáty je možné použít také tzv. anonymní metody Anonymní metody: –umožňují psát kód delegátů přímo „in-line“ –vytváří se klíčovým slovem delegate, za kterým následuje definice anonymní funkce
12/04/ Delegáty (5) Příklad: public delegate int BinOpDel(int op1, int op2); static void Main() { int sum; BinOpDel add = delegate(int op1, int op2) { return op1 + op2; }; sum = add(1, 2); Console.WriteLine(sum); }
12/04/ Delegáty (6) Knihovna dodávaná s.NET Frameworkem (BCL – Base Class Library) poskytuje také ge- nerické delegáty: –Action : delegát pro funkce bez návratové hodnoty existuje 17 různých delegátů Action s různým počtem generických parametrů: Action, Action, Action, … –Func : podobně jako Action existuje v 17 různých verzích, např. Func poslední generický parametr udává typ návratové hod- noty
12/04/ Lambda výrazy (1) Lambda výrazy jsou anonymní funkce, jež je možné přiřadit do delegáta (vznikly jako zjed- nodušení anonymních metod) Umožňují psát lokální funkce, které mohou být předány jako parametry nebo vráceny jako hodnota volání funkce Často používány při psaní výrazů LINQ Zapisovány pomocí operátoru => „přechází v“ Lambda výraz specifikuje: –seznam vstupních parametrů (může být i prázdný) na levé straně operátoru => –výraz nebo příkazový blok na straně pravé
12/04/ Lambda výrazy (2) Příklad: (int a, int b) => { return a + b; } Typy parametrů si dokáže překladač odvodit a mohou být vynechány Jestliže má tělo výrazu na pravé straně jenom jednu operaci, pak lze vynechat složené závor- ky i klíčové slovo return : (a, b) => a + b; Pokud levá strana obsahuje pouze jeden para- metr, je možné vynechat i kulaté závorky: n => n * n;
12/04/ Lambda výrazy (3) Příklad: class Program { public delegate int BinOpDel(int op1, int op2); static void Main() { BinOpDel add = (op1, op2) => op1 + op2; int sum = add(1, 2); Console.WriteLine(sum); } }