Výjimky (exceptions), generické metody a třídy v C#

Podobné dokumenty
Z. Kotala, P. Toman: Java ( Obsah )

Úvod do programování - Java. Cvičení č.4

Zápis programu v jazyce C#

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Soubor jako posloupnost bytů

Výčtový typ strana 67

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Java - výjimky. private void vstup() throws IOException {... }

Dědičnost (inheritance)

Ošetřování chyb v programech

8 Třídy, objekty, metody, předávání argumentů metod

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

29. Výjimky, jejich vznik, vyhození, odchyt a zpracování. (A7B36PVJ)

C# konzole Podíl dvou čísel, podmínka IF

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Programování v C++ 1, 17. cvičení

Generické programování

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

Algoritmizace a programování

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Simulace. Martin Pergel

PŘETĚŽOVÁNÍ OPERÁTORŮ

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

7. Datové typy v Javě

Semin aˇr Java V yjimky Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Unor 2008 Radek Koˇc ı Semin aˇr Java V yjimky 1/ 25

Objektově orientované programování

10. března 2015, Brno Připravil: David Procházka. Programovací jazyk C++

Algoritmizace a programování

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Připravil: David Procházka. Programovací jazyk C++

IRAE 07/08 Přednáška č. 7. Začátek (head)

KTE / ZPE Informační technologie

Kolekce, cyklus foreach

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

DSL manuál. Ing. Jan Hranáč. 27. října V této kapitole je stručný průvodce k tvorbě v systému DrdSim a (v

IW5 - Programování v.net a C# 4 Pokročilé konstrukce C#

PREPROCESOR POKRAČOVÁNÍ

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

8. přednáška: Soubory a proudy

17. Projekt Trojúhelníky

Jazyk C++ II. Výjimky

Základy programování. Úloha: Eratosthenovo síto. Autor: Josef Hrabal Číslo: HRA0031 Datum: Předmět: ZAP

Standardní algoritmy vyhledávací.

Mnohotvarost (polymorfizmus)

Výjimky. v C# a Javě

Úvod do programovacích jazyků (Java)

Řídicí struktury. alg3 1

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Středoškolská technika 2017 PROGRAM NA GENEROVÁNÍ PRVOČÍSEL

Sada 1 - PHP. 03. Proměnné, konstanty

Jazyk C# a platforma.net

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

1. Téma 12 - Textové soubory a výjimky

Druhy souborů. textové. binární. nestrukturované txt strukturované - ini, xml, csv. veřejné bmp, jpg, wav proprietární docx, cdr, psd

Výjimky. Tomáš Pitner, upravil Marek Šabo

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

KTE / ZPE Informační technologie

IAJCE Přednáška č. 7. řízení semaforu na křižovatce = přepínání červená/oranžová/zelená

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

Paměť počítače. alg2 1

6. Příkazy a řídící struktury v Javě

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

PB161 programování v C++ Výjimky Bezpečné programování

Textové soubory. alg9 1

Datové struktury. alg12 1

IAJCE Přednáška č. 6. logický celek, řešící dílčí část problému Příklad velmi špatného zápisu programu na výpočet obsahu obdélníku

Obsah přednášky. Příkaz for neúplný. Příkaz for příklady. Cyklus for each (enhanced for loop) Příkaz for příklady

15. Projekt Kalkulačka

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Algoritmy I. Cvičení č. 2, 3 ALGI 2018/19

DUM 06 téma: Tvorba makra pomocí VBA

6 Příkazy řízení toku

přetížení operátorů (o)

- jak udělat konstantu long int: L long velka = 78L;

1. Programování proti rozhraní

Java a XML. 10/26/09 1/7 Java a XML

Programovací jazyk Java

Programování v jazyce C a C++

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

URČITÝM ZPŮSOBEM PODOBNÉ

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Jazyk C++ I. Šablony

Programovací jazyk Pascal

Programování v C++ 1, 1. cvičení

Jazyk C# (seminář 6)

DUM 07 téma: Proměnné, konstanty a pohyb po buňkách ve VBA

5a. Makra Visual Basic pro Microsoft Escel. Vytvořil Institut biostatistiky a analýz, Masarykova univerzita J. Kalina

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

Jazyk C# (seminář 5)

Teoretické minimum z PJV

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

NPRG031 Programování II --- 2/2 Z, Zk

Řídicí příkazy KAPITOLA 3. Vstup znaků z klávesnice

Transkript:

Výjimky (exceptions), generické metody a třídy v C# Obsah VÝJIMKY (EXCEPTIONS)... 1 Chyby v programu... 2 Testování návratových hodnot funkcí... 2 Pojem výjimka... 3 Neobsloužená výjimka (unhandled exception)... 3 Vznik výjimky... 3 Ošetřování výjimek... 4 Handler... 4 Použití bloků a catch:... 5 Třídy výjimek... 6 Použití více bloků catch... 13 Blok finally... 13 Příkaz throw... 15 GENERICKÉ TŘÍDY A METODY...18 Obecnost... 18 Deklarace generické metody má tvar:... 18 Příklady generických metod:... 19 Příklad generické třídy... 21 Seznam obrázků... 22 Seznam programů... 22 Cílem kapitoly je ukázat možnosti použití výjimek a generických metod v C#. Klíčové pojmy: Výjimky obsloužené a neobsloužené, ošetření výjimek, handler, bloky, catch, throw, finály, třídy výjimek, generické metody. Výjimky (exceptions) Výjimka souvisí s výjimečným stavem, který může v programu nastat a který může vést k havárii programu (nebyl nalezen soubor, s nímž má program pracovat, dělení nulou, nedostatek paměti, ). Bude rozebrán mechanizmus výjimek vyvolání ošetření 2.11. 2011 kapitola 13 1/22

Chyby v programu Chyby - čím později se zjistí, tím je nákladnější je opravit - jsou různé chyby: některé odhalí kompilátor (nejlevnější) některé se zjistí při 1. spuštění některé vedou k havárii programu jen občas (nejnákladnější) Málo robustní chování programy zhroutí se za určitých okolností - výjimky (výjimečné situace): místo čísla zadáme písmeno dojde paměť není k dispozici disk, s nímž program pracuje dojde k přerušení spojení se sítí Programátoři s nestabilitou bojují tak, že se snaží vytvořit robustní prog., který si umí poradit s každou situací. Možné reakce programu na výjimečnou situaci: zhroutí se informuje uživatele a ukončí se informuje uživatele a nabídne mu obnovení běhu provede automatickou úpravu a pokračuje, aniž by uživatele rušil Testování návratových hodnot funkcí Chyby můžeme ošetřovat testováním návratových hodnot funkcí: Test existence souboru: if (File.Exists(@"..\..\jmena.txt")) Console.WriteLine("Soubor existuje"); Jiný způsob testování existence souboru: Definujeme instanci třídy FileInfo: FileInfo file = new FileInfo(@"..\..\jmena.txt"); if(file.exists)console.writeline("soubor existuje"); Návratové hodnoty funkcí vyjadřují úspěšnost operace (-1 se obvykle vrací v případě chyby). 2.11. 2011 kapitola 13 2/22

Zpracování výjimek v C# poskytuje mechanismus pro ošetření předvídatelných, ale neobvyklých okolností, které mohou nastat za běhu programu. Pojem výjimka Slovo výjimka může znamenat buď chybu vzniklou v programu, nebo objekt, který o ní nese informace. Neobsloužená výjimka (unhandled exception) Neobsloužená výjimka končí běhovou chybou programu s výpisem odpovídajícího hlášení, které informuje uživatele k jaké chybě došlo. Program 1 Program s neobslouženou výjimkou dělení nulou public class VstupInt static void Main() int a = Convert.ToInt32(Console.ReadLine()); int b = Convert.ToInt32 (Console.ReadLine()); double x = a/b; Console.ReadLine(); Po zadání hodnot: 10 0 Vypíše se zpráva o neobsloužené výjimce: Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. Výjimka představuje problém, vzniklý za běhu programu, který je nutno odstranit, aby mohl program pokračovat v běhu. V kódu aplikace lze výjimku obsloužit. Obsloužená výjimka nemusí ukončit program. Vznik výjimky Některé výjimky může vyvolat samo prostředí.net Framework, jiné výjimky vyvoláváme příkazem throw, za nímž uvedeme odkaz na objekt, který ponese informace o chybě. 2.11. 2011 kapitola 13 3/22

Vyvolání výjimky: throw výraz; Výraz musí představovat odkaz na instanci třídy odvozené od System.Exception. Můžeme použít odkaz na existující objekt nebo můžeme vytvořit nový objekt pomocí new. Po vzniku výjimky se přeruší přirozené pořadí provádění příkazů a program začne hledat handler, část kódu, která vzniklou situaci ošetří. Tento výraz lze za jistých okolností vynechat. Ošetřování výjimek Práce s výjimkami je v C# založena na tzv. hlídaném bloku kódu. Operace, jež se nemusí podařit, tj. při nichž může vzniknout výjimka, uzavřeme do bloku, před nějž zapíšeme klíčové slovo. Za něj pak připojíme jeden nebo několik handlerů nebo koncovku (případně obojí). Ukažme si syntaktický popis hlídaného bloku: hlídaný blok: příkazy handlery nep koncovka nep Hlídaný blok musí obsahovat alespoň jeden handler nebo koncovku (nebo obojí). Handlerů může být více, koncovka může být nejvýše jedna. Handler Handler je část programu, která může ošetřit výjimku. Jeho syntax je handler: catch( typ identifikátor ) tělo handleru catch tělo handleru První možnost začíná klíčovým slovem catch, za kterým následuje v závorkách typ výjimky, kterou může tento handler ošetřit ("typ handleru"). Musí jít o třídu odvozenou od E x c e p t i o n. Identifikátor, který následuje, bude v těle handleru představovat odkaz na objekt, který nese informace o výjimce. Budeme mu také říkat "parametr handleru". Tělo handleru je tvořeno příkazy, které se zachycenou výjimkou "něco udělají", tedy které řeší vzniklou situaci. Příklad kódu pro ošetření chyby s využitím mechanismu výjimek: 2.11. 2011 kapitola 13 4/22

// Nějaké nebezpečné funkce catch(nedostatekpameti) //Provedení nějakých akcí, které ošetřují nedostatek paměti catch(soubornenalezen) //Provedení jiné akce, která ošetřuje, že soubor nebyl nalezen Použití bloků a catch: Není jednoduché přijít na to, kam bloky umístit- nemusí být vždy zřejmé, které akce mohou vyvolat výjimky. Umístění : na místa alokace paměti využití zdrojů chyby, související s hraničními hodnotami neoprávněné vstupy. Význam klíčových slov: (zkusit) catch (zachytit) throw (zamítnout) finally (ukončení) Jinou možnost nám nabízí mechanizmus výjimek Hlídanou posloupnost příkazů označíme do zvláštního bloku ()- v tomto bloku může vzniknout výjimka. Za tímto blokem postupně uvedeme, jaké výjimky mohly v hlídaném bloku nastat, a jak je ošetřit. Co v C# může být výjimkou: proměnná jakéhokoliv primitivního datového typu instance jakékoliv třídy. Výjimka by v sobě měla nést nějakou informaci o situaci, která nastala a proč byla vyvolána. Syntaxe výjimek v C#: Výjimka se vyvolá (vyvrhne) pomocí klíčového slova throw. Hlídaný blok se značí klíčovým slovem. K odchycení vyvolaných výjimek slouží klíčové slovo catch. 2.11. 2011 kapitola 13 5/22

Třídy výjimek V C# je výjimka objektem vytvořeným (nebo) vyvolaným) v okamžiku vzniku výjimečného stavu. Zmiňovaný objekt obsahuje veškeré informace, nezbytné k nalezení problému. Třídy výjimek můžeme vytvářet sami. Můžete však čerpat z ohromného rezervoáru předdefinovaných tříd výjimek integrovaných do základní knihovny tříd ( BCL, Base Class Library) platformy.net Framework. Bázové třídy výjimek Hierarchie tříd odvozených od třídy System.Exception object Exception SystemException IndexOutOfRangeException ArithmeticException InvalidCastException DivideByZeroExceptio OverflowExceptio Obrázek 1 Hierarchie tříd výjimek 2.11. 2011 kapitola 13 6/22

Třídy pro přenos informací o výjimkách Třídy pro přenos informací o výjimkách jsou ve jmenném prostoru System. Napíšete-li ve vývojovém prostředí Microsoft Visual Studio System., objeví se všechny členy jmenného prostoru System mezi jiným i třídy výjimek. Ty jsou ukončeny slovem Exception. Jestliže v editoru vývojového prostředí Microsoft Visual Studio nastavíte kurzor nad metodu ReadLine() u příkazu: int a = Convert.ToInt32(Console.ReadLine()); objeví se bublinková nápověda, která zobrazuje třídy výjimek, které mohou být aktivované v této metodě: System.IO.IOException System.FormatException System.OverflowException Zadáme-li na vstupu nečíselný znak, vznikne formátovací chyba: System.FormatException Zadáme-li příliš velké číslo (například 123456789456123123456), může vzniknout System.OverflowException Ošetření uvedeného kódu ukazuje následující program: Program 2 Ošetření výjimek pro načení celého čísla a dělení nulou public class Program static void Main() int a = Convert.ToInt32(Console.ReadLine()); int b = Convert.ToInt32(Console.ReadLine()); double x = a / b; catch (FormatException) Console.WriteLine("Není zadané celé číslo"); catch (DivideByZeroException) Console.WriteLine("Dělení nulou"); catch (OverflowException) Console.WriteLine("Příliš velké číslo"); 2.11. 2011 kapitola 13 7/22

Console.ReadLine(); Následující program zajišťuje správné zadání celého čísla: musí obsahovat pouze číslice a nesmí překročit hodnotu int.maxvalue. Program 3 Ošetření čtení celého čísla pomocí mechanismu výjimek public class VstupInt static int cislo; public static bool TestInt() cislo = Convert.ToInt32(Console.ReadLine()); return true; catch (FormatException) Console.WriteLine("Chybně zadané čislo"); return false; catch (OverflowException) Console.WriteLine("Příliš velké číslo"); return false; public static int CtiInt() bool f; do Console.WriteLine("Zadej celé čislo: "); f = TestInt(); while (!f); return cislo; public static void Main() int i = CtiInt(); Console.WriteLine(i); Podobně lze ošetřit zadávání hodnoty do znakové proměnné, nebo do proměnné typu double. 2.11. 2011 kapitola 13 8/22

Program 4 Ošetření čtení racionálního čísla pomocí mechanismu výjimek public class Vstup static double dcislo; public static bool TestDouble() dcislo = Convert.ToDouble(Console.ReadLine()); return true; catch (FormatException) Console.WriteLine("Chybně zadané číslo"); return false; public static double CtiDouble() bool f; do Console.WriteLine("Zadej racionální číslo: "); f = TestDouble(); while (!f); return dcislo; public static void Main() double d = CtiDouble(); Console.WriteLine(d); V další části programu je ukázáno, jak lze ošetřit, aby uživatel mohl zadávat v racionálním čísle jak desetinnou čárku, tak desetinnou tečku: Program 5 Ošetření čtení racionálního čísla - umožňuje zadat. i, public class Vstup static double dcislo; public static bool TestDouble() dcislo = Convert.ToDouble(Console.ReadLine().Replace('.', ',')); return true; catch (FormatException) Console.WriteLine("Chybně zadané číslo"); return false; 2.11. 2011 kapitola 13 9/22

public static double CtiDouble() bool f; do Console.WriteLine("Zadej racionální číslo: "); f = TestDouble(); while (!f); return dcislo; public static void Main() double d = CtiDouble(); Console.WriteLine(d); Po načtení řetězce se pomocí metody Replace('.', ',') nahradí výskyt '.' (pokud existuje) ','. Program 6 Ošetření čtení racionálního znaku pomocí mechanismu výjimek public class VstupInt static char znak; public static bool TestChar() znak = Convert.ToChar(Console.ReadLine()); return true; catch (FormatException) Console.WriteLine("Chybně zadaný znak"); return false; public static char CtiZnak() bool f; do Console.WriteLine("Zadej znak: "); f = TestChar(); while (!f); return znak; public static void Main() char c = CtiZnak(); Console.WriteLine(c); 2.11. 2011 kapitola 13 10/22

Následující program obsahuje všechny uvedené kontroly: Program 7 Kontrola vstupu znaku, celého a racionálního čísla public class Vstupy static char znak; public static bool TestChar() znak = Convert.ToChar(Console.ReadLine()); return true; catch (FormatException) Console.WriteLine("Chybně zadaný znak"); return false; static double dcislo; static bool f; public static bool TestDouble() dcislo = Convert.ToDouble(Console.ReadLine().Replace('.', ',')); return true; catch (FormatException) Console.WriteLine("Chybně zadané číslo"); return false; static int cislo; public static bool TestInt() cislo = Convert.ToInt32(Console.ReadLine()); return true; catch (FormatException) Console.WriteLine("Chybně zadané číslo"); return false; public static char CtiZnak() do 2.11. 2011 kapitola 13 11/22

Console.WriteLine("Zadej znak: "); f = TestChar(); while (!f); return znak; public static double CtiDouble() do Console.WriteLine("Zadej racionální číslo: "); f = TestDouble(); while (!f); return dcislo; public static int CtiInt() do Console.WriteLine("Zadej celé číslo: "); f = TestInt(); while (!f); return cislo; public static void Main() int i = CtiInt(); Console.WriteLine(i); double d = CtiDouble(); Console.WriteLine(d); char c = CtiZnak(); Console.WriteLine(c); Program 8 Indikace přetečení indexu class PreteceniIndexu static void Main() int[] cisla = new int[5]; // deklarace pole typu int o délce 5 // blok kódu hlídající chyby Console.WriteLine("Před generováním chyby"); cisla[10] = 12; // přetečení indexu pole Console.WriteLine("Sem se nedostanu"); catch (IndexOutOfRangeException) // zachycení výjimky Console.WriteLine("Přetečení indexu"); Console.WriteLine("Po chybě"); 2.11. 2011 kapitola 13 12/22

Použití více bloků catch Různé chyby generují různé druhy výjimek. Proto je třeba napsat více bloků catch za sebou. Dobrá vlastnost tohoto uspořádání je, že CLR (common language runtime) nasměruje program na správný blok catch, který je určen pro danou výjimku na základě jejího typu. Spojení výjimky s blokem catch se provede automaticky. Blok finally Výjimky způsobí skok v programu a nelze zaručit, že se nějaký příkaz spustí po ukončení předchozího, protože může dojít k vygenerování výjimky. Řešením je napsat příkaz, který má být vykonán za všech okolností v bloku finally. Blok finally můžete psát pouze bezprostředně po bloku nebo bezprostředně za poslední blok catch. Pokud program vstoupí do bloku, který je asociován s blokem finally, bude blok finally vždy spuštěn. Program 9 Indikace dvou chyb: dělení nulou a přetečení indexu class Osetreni2Vyjimek public static void Main() int[] cisla = new int[5]; int a = 5; int b = 0; // blok kódu hlídající chyby Console.WriteLine("Před generováním chyby"); a = a / b; // dělení nulou cisla[7] = 11; // přetečení indexu pole Console.WriteLine("Sem se nedostanu"); catch(dividebyzeroexception) // zachycení výjimky Console.WriteLine("Děleni nulou"); a = 0; catch(indexoutofrangeexception) // zachycení výjimky Console.WriteLine("Přetečení indexu"); finally Console.WriteLine("Toto se vypíše úplně vždy"); Program 10 Ošetření výjimky FileNotFoundException using System.IO; 2.11. 2011 kapitola 13 13/22

class Pokus public static StreamReader sr; public static int OtevreniSouboru() // Čtení souboru sr = new StreamReader("..\\..\\Program1.cs"); return 0; catch (FileNotFoundException) Console.WriteLine("Soubor neexistuje"); return -1; static void Main() if (OtevreniSouboru()!= -1) string mystring = sr.readtoend(); sr.close(); // Zobrazení obsahu souboru. Console.WriteLine(myString); // Čekání na stisk klávesy. Console.ReadLine(); Program 11 Opakované dělení dvou čísel, dokud nezadáme nulu class Pokus public static double deleni(int a, int b) int c=a / b; return (double)a / (double)b; catch (DivideByZeroException) Console.WriteLine("Nulou dělit nelze"); return 0; static void Main(string[] args) int a, b; do Console.WriteLine("Zadej dělěnce (0 končí cyklus):"); a = Convert.ToInt32(Console.ReadLine()); if(a==0)break; Console.WriteLine("Zadej dělitele:"); 2.11. 2011 kapitola 13 14/22

b = Convert.ToInt32(Console.ReadLine()); double x = deleni(a, b); if(x!=0)console.writeline("podíl je: 0:F2",x); while(a!=0); Příkaz throw Výjimku můžeme vyhodit manuálně pomocí příkazu throw: throw objektvyjimky; Příkaz throw vyhazuje object. Program 12 Výpočet průměru pěti známek V dalším příkladu si program vyžádá zadání známky. Pokud uživatel zadá číslo mimo interval 1 až 5, generuje se výjimka Pokud uživatel zadá správnou známku, výjimka se nevygeneruje a zadaná známka se přičte do vytvářeného součtu. Po zadání pěti správných známek se vypíše jejich průměr. class NeniZnamka:Exception public void vypis() class Program Console.WriteLine("Špatně zadaná známka"); static NeniZnamka n = new NeniZnamka(); static void Main() int z=0,i=0,s=0; do Console.WriteLine("Zadej hodnotu známky: "); z = Convert.ToInt32(Console.ReadLine()); if (z > 5 z < 1) throw n; s += z; i++; catch(neniznamka n) 2.11. 2011 kapitola 13 15/22

n.vypis(); while(i<5); Console.WriteLine("Průměr známek je: 0", (double)s/5.0); Console.ReadLine(); Program 13 Výpočet průměru známek - zadávání je ukončeno nulovou hodnotou public class VstupInt public static int CtiInt() int i=0; bool b = false; do Console.WriteLine("Zadej známku: "); i = Convert.ToInt32(Console.ReadLine()); if (i < 0 i > 5) throw new ArithmeticException(); b = true; catch (FormatException) Console.WriteLine("Chybně zadané číslo!"); b = false; catch (ArithmeticException) Console.WriteLine("Známka je mimo rozsah"); b = false; while (!b); return i; static void Main() int a, S = 0, p = 0; do a = CtiInt(); S += a; p++; while (a!= 0); Console.WriteLine("Průměr správně zadaných známek je: 0:F2", (double)s/(double)(--p)); Console.ReadLine(); 2.11. 2011 kapitola 13 16/22

Program 14 Určení názvu dne v týdnu Následující program implementuje metodu DT, která má jeden celočíselný argument den, reprezentující číslo dne v týdnu. Metoda vrací řetězec, který je název příslušného dne v týdnu. Řešení je provedeno příkazem switch, kde v případě nesprávně zadaného čísla se vytvoří objekt třídy ArgumentOutOfRangeException a v odpovídajícím bloku catch je vypsáno příslušné hlášeni: "Číslo je mimo rozsah". public class Den_v_Tydnu public static string DT(int den) switch(den) case 1: return "Pondělí"; case 2: return "Úterý"; case 3: return "Středa"; case 4: return "Čtvrtek"; case 5: return "Pátek"; case 6: return "Sobota"; case 7: return "Neděle"; default: throw new ArgumentOutOfRangeException(); public static string CtiInt() int den = 0; string s=""; Console.WriteLine("Zadej číslo dne v týdnu: "); den = Convert.ToInt32(Console.ReadLine()); s = DT(den); catch (FormatException) Console.WriteLine("Chybně zadané číslo!"); catch (ArgumentOutOfRangeException) Console.WriteLine("Číslo je mimo rozsah"); return s; static void Main() Console.WriteLine(CtiInt()); Console.ReadLine(); 2.11. 2011 kapitola 13 17/22

Generické třídy a metody Dva nejdůležitější rysy jazyků vyšší úrovně jsou obsluha výjimek. generika (šablony) a Generické typy jsou definovány ve standardu C# a podporovány moderními překladači. Umožňují vytvářet znovupoužitelný a přizpůsobitelný kód. Generika (šablony typů) jsou konstrukce, v nichž typ dat je určen jako parametr - umožní použít jednu funkci nebo třídu pro několik různých typů dat. Podle šablon může překladač vytvářet celé skupiny podobných tříd nebo funkcí, které se navzájem liší jen v některých datových typech nebo v hodnotách některých konstant. Takto vytvořené funkce nebo třídy označujeme jako instance šablony. Generické metody a třídy umožňují obecnou definici algoritmu, kde konkrétní typ datových položek je uvedený až při vytvoření příslušných objektů a spuštění metod. Obecnost Obecnost je taková konstrukce třídy, která umožňuje dodání jedné nebo více jejích interně používaných částí až za běhu aplikace. Příklad Chceme použít nějaký algoritmus (např. třídění) na různé druhy dat (čísla, znaky, řetězce). V C# se parametrizovaná třída nazývá šablona typů. Obecná definice šablonové metody: < Typ> návratový_typ jméno(seznam parametrů) // tělo metody Obecná definice šablonové t:řídy, obsahující šablonové metody class NázevTřídy<Typ>; Deklarace generické metody má tvar: public static Ttyp identifikator<ttyp>(parame)příkazy Ttyp je typ dat, použitý metodou. V závorkách < > je parametr šablony. v závorkách ( ) jsou parame metody Definice ze standardní knihovny C++ (STL) jsou většinou založeny na šablonách. Překladač kontroluje syntaktickou správnost šablony v okamžiku, kdy narazí na její definici. Šablona funkce umožňuje vytvořit funkci na základě parametrů - parametrické programování. 2.11. 2011 kapitola 13 18/22

Příklady generických metod: Program 15 Generická metoda vrat1 vrací hodnotu prvního parametru V uvedeném programu generická metoda vrat1 vrátí hodnotu prvního argumentu pro různé typy dat. using System.Collections.Generic; class Generika public static T vrat1<t>(t a, T b) return a; public static void Main() int i = 1, j = 2; double a = 1.5, b = 1.2; char c='#',d='@'; string s1 = "Petr", s2 = "Pavel"; Console.WriteLine("0", vrat1(i, j)); Console.WriteLine("0", vrat1(a, b)); Console.WriteLine("0", vrat1(c, d)); Console.WriteLine("0", vrat1(s1, s2)); Console.ReadLine(); Program vypíše: 1 1,5 # Petr Program 16 Generická metoda prohod prohodí hodnoty svých dvou parametrů Další program prohodí obsah prvního a druhého argumentu generické metody prohod using System.Collections.Generic; class Generika public static void prohod<t>(ref T a, ref T b) T pom; pom = a; a = b; b = pom; ; public static void Main() 2.11. 2011 kapitola 13 19/22

int i = 1, j = 2; double a = 1.5, b = 1.2; char c = '#', d = '@'; string s1 = "Petr", s2 = "Pavel"; prohod<int>(ref i, ref j); prohod<double>(ref a, ref b); prohod<char>(ref c, ref d); prohod<string>(ref s1, ref s2); Console.WriteLine("0 1", i, j); Console.WriteLine("0 1", a, b); Console.WriteLine("0 1", c, d); Console.WriteLine("0 1", s1, s2); Console.ReadLine(); Obecný datový typ T je uvedený za názvem generické metody v lomených závorkách je to programátorem zvolený identifikátor (zde T jako template = šablona). Tento datový typ je dále použitý pro definování formálních parametrů metody namísto konkrétního datového typu. V Mainu jsou definované proměnné i,j typu int a a,b, typu double. Při volání generické metody prohod je třeba za jejím názvem uvést konkrétní datový typ argumentů v prvním případě int, v druhém double v lomených závorkách. Program 17 Generická metoda Spojeni spoji hodnoty svých parametrů, převedené na řetězce using System.Collections.Generic; class Generika public static string Spojeni<T>(ref T a, ref T b) return a.tostring()+" "+b.tostring(); public static void Main() int i = 1, j = 2; double a = 1.5, b = 1.2; char c = '#', d = '@'; string s1 = "Petr", s2 = "Pavel"; Console.WriteLine("0", Spojeni<int>(ref i, ref j)); Console.WriteLine("0", Spojeni<double>(ref a, ref b)); Console.WriteLine("0", Spojeni<char>(ref c, ref d)); Console.WriteLine("0", Spojeni<string>(ref s1, ref s2)); Console.ReadLine(); 2.11. 2011 kapitola 13 20/22

Příklad generické třídy Program 18 Příklad generické třídy Následující program ukazuje definici a použití generické třídy Spojeni, která obsahuje přetíženou generickou metodu Spoj bez parametrů a se dvěma parame a konstruktor, který nastaví hodnoty privátních proměnných x,y na hodnoty svých parametrů. Vstupní bod programu (Main) je ve třídě Program a jsou zde vytvořeny čtyři objekty různých datových typů a konstruktorem třídy Spojeni proměnných jsou nastaveny hodnoty privátních pro konkrétní datové typy. Potom je pomocí těchto vytvořených objektů zavolaná neparametrická a následně parametrická metoda Spoj pro vypsání návratové hodnoty, která spojí hodnoty dvou proměnných obecného typu, převedené na řetězce. using System.Collections.Generic; class Spojeni<T> T x, y; public Spojeni(T x,t y) this.x=x; this.y=y; public string Spoj() return x.tostring() + " " +y.tostring(); public string Spoj(T x,t y) return x.tostring() + " " + y.tostring(); class Program public static void Main() Spojeni<int> s1 = new Spojeni<int>(10, 20); Spojeni<double> s2 = new Spojeni<double>(10.123, 20.321); Spojeni<char> s3 = new Spojeni<char>('#','@'); Spojeni<string> s4 = new Spojeni<string>("Otec", "Matka"); Console.WriteLine("Volání neparametrické metody Spoj:"); Console.WriteLine(s1.Spoj()); Console.WriteLine(s2.Spoj()); Console.WriteLine(s3.Spoj()); Console.WriteLine(s4.Spoj()); Console.WriteLine("\nVolání parametrické metody Spoj:"); Console.WriteLine(s1.Spoj(20,10)); Console.WriteLine(s2.Spoj(20.321,10.123)); Console.WriteLine(s3.Spoj('@','#')); Console.WriteLine(s4.Spoj("Matka","Otec")); Console.ReadLine(); 2.11. 2011 kapitola 13 21/22

Seznam obrázků Obrázek 1 Hierarchie tříd výjimek... 6 Seznam programů Program 1 Program s neobslouženou výjimkou dělení nulou... 3 Program 2 Ošetření výjimek pro načení celého čísla a dělení nulou... 7 Program 3 Ošetření čtení celého čísla pomocí mechanismu výjimek... 8 Program 4 Ošetření čtení racionálního čísla pomocí mechanismu výjimek... 9 Program 5 Ošetření čtení racionálního čísla - umožňuje zadat. i,... 9 Program 6 Ošetření čtení racionálního znaku pomocí mechanismu výjimek... 10 Program 7 Kontrola vstupu znaku, celého a racionálního čísla... 11 Program 8 Indikace přetečení indexu... 12 Program 9 Indikace dvou chyb: dělení nulou a přetečení indexu... 13 Program 10 Ošetření výjimky FileNotFoundException... 13 Program 11 Opakované dělení dvou čísel, dokud nezadáme nulu... 14 Program 12 Výpočet průměru pěti známek... 15 Program 13 Výpočet průměru známek - zadávání je ukončeno nulovou hodnotou... 16 Program 14 Určení názvu dne v týdnu... 17 Program 15 Generická metoda vrat1 vrací hodnotu prvního parametru... 19 Program 16 Generická metoda prohod prohodí hodnoty svých dvou parametrů... 19 Program 17 Generická metoda Spojeni spoji hodnoty svých parametrů, převedené na řetězce... 20 Program 18 Příklad generické třídy... 21 2.11. 2011 kapitola 13 22/22