Metody s proměnným počtem parametrů Jazyk C# umožňuje definovat metody akcep-tující variabilní počet skutečných parametrů Pro definici metody s proměnným počtem pa-rametrů se využívá modifikátor params Modifikátor params může být uvedený pou-ze před posledním parametrem metody Parametr zapsaný za params musí být vždy typu pole 18/04/2018
Rozšiřující metody Umožňují rozšířit existující datový typ (třídu nebo strukturu) dodatečnými statickými me-todami Tyto metody jsou okamžitě k dispozici jakým-koliv příkazům, které se odkazují na data roz-šířeného typu Definují se ve statické třídě Typ, kterého se rozšiřující metoda týká, se uvádí jako první parametr metody společně s klíčovým slovem this 18/04/2018
Řetězce Řetězec představuje posloupnost znaků, tj. hodnot typu char Jednotlivé znaky lze zpřístupnit pomocí jejich indexů (zapisovaných v hranatých závorkách) Narozdíl od jazyka C řetězce nejsou ukonče-ny znakem ’\0’ Řetězce mohou být v jazyku C# reprezento-vány např.: datovým typem string (synonymum pro bázo-vou třídu System.String) třídou StringBuilder (definována ve jmen-ném prostoru System.Text) 18/04/2018
Třída String (1) Definována ve jmenném prostoru System Slouží pro ukládání řetězců a práci s nimi Délku řetězce (počet znaků) lze získat pomocí vlastnosti Length Obsahuje mimo jiné přetížený operátor: + pro zřetězení (spojení) dvou řetězců == pro porovnání dvou řetězců na rovnost Poskytuje také sadu metod, např.: Compare, CompareOrdinal: lexikograficky porovnává řetězce se (bez) zohledně-ním (zohlednění) místního jazykového nastavení 18/04/2018
Třída String (2) Format: IndexOf, LastIndexOf: Insert: nahrazuje formátovací značky ({0}, {1} apod.) v ře-tězci hodnotami dalších parametrů IndexOf, LastIndexOf: najde první (poslední) výskyt podřetězce nebo znaku v řetězci Insert: vloží (od zadané pozice) podřetězec do řetězce PadLeft, PadRight: doplní zleva (zprava) řetězec opakováním daného znaku Remove: vymaže část řetězce 18/04/2018
Třída String (3) Replace: Split: Substring: ToLower, ToUpper: nahradí výskyty daného řetězce zadaným řetězcem nebo znakem Split: rozdělí řetězec na podřetězce k rozdělení dojde v místech nalezení zadaného znaku Substring: vrátí podřetězec začínající na zadané pozici v řetězci ToLower, ToUpper: převede řetězec na malá (velká) písmena TrimStart, TrimEnd, Trim: odstraní ze začátku (konce, začátku i konce) řetězce mezery 18/04/2018
Třída String (4) Poznámky: řetězec reprezentovaný třídou string je neměn-ný (immutable) metody manipulující s řetěz-cem vytvářejí novou instanci znaky na dané pozici (indexu) se chovají jako read-only, tj. není možné provést přiřazení (zápis) znaku na zadanou pozici, např zápis.: string s = ”Hello world”; s[1] = ’a’; //nelze způsobí chybu 18/04/2018
Třída StringBuilder (1) Definována ve jmenném prostoru System.Text Při úpravě řetězců reprezentovaných třídou StringBuilder nedochází k vytváření nové instance, ale upravuje se stávající obsah Nová paměť je alokována pouze v případě, že po vykonané operaci řetězec přesahuje speci-fikovanou kapacitu Vykazuje větší efektivitu při operacích jako jsou např. zřetězení řetězců, náhrada části řetězce, vkládání znaků do řetězce apod. 18/04/2018
Třída StringBuilder (2) Poskytuje např. metody: Append: připojení řetězce Insert: vložení řetězce Remove: odstranění znaků z řetězce Replace: nahrazení výskytu znaku nebo podřetězce jiným zna-kem nebo podřetězcem ToString: vrací obsah řetězce přetypovaný na string 18/04/2018
Třída StringBuilder (3) Poznámky: třída StringBuilder definuje také vlastnosti: Length: zpřístupňuje aktuální délku řetězce Capacity: určuje maximální počet znaků, pro něž je v současné instanci alokované paměťové místo u instancí třídy StringBuilder lze přiřadit znak na zadaný index (pozici) 18/04/2018
Podmíněný operátor (1) Ternární operátor umožňující zkrácený zápis příkazové struktury if … else Umožňuje vyhodnotit podmínku a vrátit jednu hodnotu v závislosti na tom, je-li podmínka splněna nebo nesplněna Zapisovaný ve tvaru: podmínka ? splněno : nesplněno kde: podmínka: booleovský výraz, který se vyhodnotí 18/04/2018
Podmíněný operátor (2) splněno: hodnota, která se vybere v případě splnění podmínky nesplněno: hodnota, která se vybere v případě nesplnění podmínky Příklad: int x; string s = x.ToString() + ” ”; s += (x == 1? ”člověk” : ”lidé”); Console.WriteLine(s); 18/04/2018
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) 18/04/2018
Iterátory (2) Návratovým typem metody představující iterá-tor musí být: IEnumerator, IEnumerator<T> IEnumerable, IEnumerable<T> 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 18/04/2018
Iterátory (3) Příklad: public static IEnumerable<int> 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(); } 18/04/2018
Výjimky a zpracování chyb (1) Výjimky (exceptions) dovolují tvorbu progra-mů, které mohou reagovat na různé chybové stavy vzniklé v jeho průběhu Cílem výjimek je učinit programy robustnější tím, že jsou rozšířeny o schopnosti správy chyb vzniklých na úrovni aplikace nebo operačního systému Výjimky v jazyku C#: jsou objektově orientované oddělují zpracování chyb od výkonného kódu nejsou hlídané (jsou unchecked) by měly být dokumentovány 18/04/2018
Výjimky a zpracování chyb (2) Každá výjimka v jazyku C# je: objekt odvozena z třídy Exception nebo z některé z je-jich následníků obsahuje informace o: svém původu důvodu vzniku Pomocí zachycení výjimky je možné nastalý (chybový) stav zpracovat (obsloužit) Jestliže dojde ke vzniku výjimky, která není ni-jak obsloužena, pak dochází k ukončení progra-mu s odpovídající běhovou chybou 18/04/2018
Výjimky a zpracování chyb (3) Mechanismus výjimek je v jazyce C# založen na klíčových slovech: try: vymezuje začátek chráněného bloku kódu jestliže nějaká operace v tomto bloku způsobí výjimku, pak je okamžitě řízení předáno do bloku, který je umí-stěný za klíčovým slovem catch catch: slouží k zápisu bloku, který se provede jestliže ve sdruženém chráněném bloku dojde ke vzniku výjimky po bloku try může následovat více bloků catch, z nichž každý slouží pro ošetření specifického typu výjimky 18/04/2018
Výjimky a zpracování chyb (4) blok catch se zapisuje ve tvaru: catch (typ_výjimky proměnná) { ošetření výjimky } proměnná obsahuje objekt vyjadřující podrobné úda-je o vzniklé výjimce (např. vlastnost Message obsa-huje textový popis chyby, která způsobila výjimku) poznámka: proměnná může být v zápisu bloku catch vynechána finally: udává volitelný blok používaný většinou k uvolnění zdrojů alokovaných v bloku try 18/04/2018
Výjimky a zpracování chyb (5) příkazy v tomto bloku jsou vykonány vždy, tzn. v pří-padě výskytu výjimky i v případě normálního prove-dení throw: slouží k vyvolání výjimky Jestliže při provádění příkazů v bloku try dojde ke vzniku výjimky, které neodpovídá žádný blok catch, potom: metoda, v níž byl použitý blok try je ukončena a řízení se vrátí do volající metody jestliže volající metoda používá blok try, pak se hledá ošetření výjimky v blocích catch tohoto bloku try 18/04/2018
Výjimky a zpracování chyb (6) jestliže volající metoda nepoužívá blok try nebo nedefinuje odpovídající ošetření v bloku catch, pak je volající metoda ukončena a řízení se vrací její volající metodě, kde se celý proces opakuje pokud je nakonec nalezeno ošetření vzniklé vý-jimky, tak se provedou příkazy popsané v přísluš-ném bloku catch a poté se pokračuje prvním příkazem za blokem catch v metodě, která vý-jimku zachytila není-li nikde nalezeno ošetření vzniklé výjimky, pak je program ukončen 18/04/2018
Třída Exception (1) Definována ve jmenném prostoru System Reprezentuje chyby, ke kterým dochází v době běhu programu Slouží jako výchozí třída pro všechny další vý-jimky Definuje např. vlastnosti: Message: vrací řetězec (text) popisující vzniklou výjimku je nastavena jako parametr konstruktoru Source: vrací nebo nastavuje jméno aplikace nebo objektu, který výjimku vyvolal 18/04/2018
Třída Exception (2) StackTrace: HelpLink: InnerException: vrací stav zásobníku v době vzniku výjimky posloupnost metod, které vedly k vyvolání výjimky příklad (zaformátováno): at Excep.Program.Div(Int32 a, Int32 b) in c:\Excep\Excep\Program.cs:line 17 at Excep.Program.Main(String[] args) in c:\Excep\Excep\Program.cs:line 27 poznámka: program musí být přeložený v režimu debug HelpLink: vrací nebo nastavuje URL na soubor popisující chybu InnerException: obsahuje informace o předcházející výjimce, která způso-bila současnou výjimku předcházející výjimka je zaznamenána předáním (jako pa-rametr) konstruktoru současné výjimky 18/04/2018
Rozdělení výjimek Výjimky v .NET Frameworku byly původně roz-dělovány do dvou skupin, jimž odpovídají třídy (potomci třídy Exception): SystemException: pro výjimky CLR (Common Language Runtime), tj. pro běhové prostředí, které se stará o spouštění programů, správu paměti, typovou bezpečnost nebo o výjimky ApplicationException: pro výjimky uživatelských aplikací Zmíněné: rozdělení dnes často není dodržováno ani v BCL třídy zůstávají zachovány pro zpětnou kompatibiltu 18/04/2018
Typy výjimek (1) Třídy reprezentující výjimky pro parametry: ArgumentException: potomek třídy SystemException byl předán parametr s neplatnou hodnotou pomocí vlastnosti ParamName lze zjistit jméno paramet-ru, který tuto výjimku způsobuje ArgumentNullException: potomek třídy ArgumentException metodě byl předán parametr s hodnotou null, přičemž tato metoda jej neakceptuje jako platný parametr ArgumentOutOfRangeException: hodnota parametru je mimo povolený rozsah 18/04/2018
Typy výjimek (2) Třídy pro aritmetické výjimky: ArithmeticException: potomek třídy SystemException nastala chyba při aritmetické operaci nebo při převodu DivideByZeroException: potomek třídy ArithmeticException došlo k dělení nulou OverflowException: aritmetická operace nebo převod skončil přetečením vý-sledku 18/04/2018
Typy výjimek (3) vznik přetečení není standardně hlídán hlídání přetečení lze zapnout, resp. vypnout v nastavení projektu pomocí klíčových slov checked, resp. unchecked příklad: int x = int.MaxValue; checked { x++; //vyvolá výjimku OverflowException } int x = int.MaxValue; unchecked { x++; //nevyvolá výjimku OverflowException } 18/04/2018
Typy výjimek (4) Třídy pro výjimky při provádění I/O operací (de-finovány ve jmenném prostoru System.IO): IOException: potomek třídy SystemException bázová třída pro chyby při zpracování vstupu a výstupu FileNotFoundException: potomek třídy IOException vzniká při pokusu o zpřístupnění neexistujícího souboru PathTooLongException: dochází k ní jestliže cesta nebo název souboru je delší než systémem definované maximum 18/04/2018
Typy výjimek (5) Další třídy reprezentující výjimky (odvozeny od třídy SystemException): InvalidOperationException: metodu není možné spustit, protože objekt není ve valid-ním stavu například zápis do proudu, který ještě nebyl otevřen FormatException: formát vstupu neodpovídá požadavkům příklad: Convert.ToInt32(”Program”) může být vyvolána i např. v případě čtení ze souboru nebo zařízení IndexOutOfRangeException: pokus o manipulaci v poli s prvkem, jehož index je mimo rozsah pole 18/04/2018
Typy výjimek (6) NullReferenceException: InvalidCastException: pokus se o dereferencování objektu, který je null například pokus o vyvolání jeho metody aplikace by neměla tuto výjimku vyvolávat InvalidCastException: vzniká při pokusu o neplatné přetypování příklad: (int) ”Program” OutOfMemoryException: není dostatek paměti pro pokračování programu aplikace by neměla tuto výjimku vyvolávat ani zachytávat 18/04/2018
Typy výjimek (7) StackOverflowException: došlo k přetečení prováděcího zásobníku (obvykle příliš mnoho volaných metod) aplikace by neměla tuto výjimku vyvolávat ani zachytávat příklad: public string BadProperty { get { return badProperty; } set //StackOverflowException BadProperty = value; } } 18/04/2018
Práce s výjimkami (1) Konvence: nově vytvářená výjimka (třída reprezentující výjim-ku) by měla: být odvozena od třídy Exception nebo od nějakého následníka třídy Exception název výjimky končí slovem Exception Bývá vhodné přidat vlastnosti pro další infor-mace: není vhodné předávat všechny důležité informace jen pomocí vlastnosti Message 18/04/2018
Práce s výjimkami (2) Výjimky by měly být používány jen pro výji-mečné stavy: zpracování výjimky je náročnější než použití podmí-něného příkazu jestliže lze chybu očekávat často, je lepší ji řešit pro-gramově (pomocí podmíněného příkazu nebo návra-tové hodnoty) Nikdy by: neměla být vyvolávána výjimka přímo třídy Exception neměl být použitý prázdný blok catch normální užívání třídy nemělo způsobit výjimku 18/04/2018
Práce s výjimkami (3) Výjimka může být v programu vyvolána pomo-cí klíčového slova throw Blok catch, který danou výjimku zachytí, mů-že přidat další doplňující informace a provést je-jí opětovné vyvolání Příklad: try { ... } catch (Exception ex) { ... throw; } 18/04/2018
Práce s výjimkami (4) nebo: try { ... } catch (Exception ex) { ... throw ex; } Je-li při opětovném vyvolání výjimky použita proměnná, jež výjimku reprezentuje, dojde k re-setování zásobníku (stack trace), v němž jsou uchovávány informace o vzniklých výjimkách 18/04/2018