C# – 3. lekce
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

C# – 3. lekceC# – 3. lekce

 

C# – 3. lekce

Google       Google       4. 7. 2006       50 281×

  • Generika
  • Výjimky
  • Události

V tomto díle kurzu budeme naposledy využívat prostředí konzole. Abychom mohli vyrazit dále, potřebujeme ovládat následující.

Generika

.NET Framework 2.0 přivedl na svět způsob, jak se zbavit boxingu a unboxingu – generiku. Generika umožňuje pracovat s objekty, o kterých nevíme, jakého typu jsou.

V prvním díle tohoto kurzu jsem si popsali práci se seznamem pomocí třídy List:


List<float> seznam = new List<float>();

Jak vidíte, při vytváření instance zadáváme do špičatých závorek název třídy, se kterou bude seznam pracovat. Třída pak při manipulaci s objekty nemusí provádět boxing a unboxing. Tato třída je tedy typickým představitelem generiky.

Nyní si ukážeme příklad definice naší vlastní generické třídy:


class GenericClass<X, Y>
    {
        private X prvekX;
        private Y prvekY;

        public GenericClass(X valX, Y valY)
        {
            prvekX = valX;
            prvekY = valY;
        }

        public override string ToString()
        {
            return "Prvek X: "+prvekX.ToString()+"\nPrvek Y: "+prvekY.ToString();
        }

        public string GetInfo()
        {
            return "Prvek X implementuje "+prvekX.GetType().GetMethods().Length.ToString()+" metod\nPrvek Y implementuje "+prvekY.GetType().GetMethods().Length.ToString()+" metod";        
        }
    }

Použijeme naši třídu:


GenericClass<DateTime, string> test = new GenericClass<DateTime, string>(DateTime.Now,"nějaký text");
Console.WriteLine(test.ToString());
Console.WriteLine(test.GetInfo());

Nadefinovali jsme si generickou třídu, která pracuje s prvky typu X a Y. V konstruktoru těmto prvkům přiřadíme hodnoty. Metoda GetInfo vrací řetězec, který obsahuje počet metod třídy X a Y. Metoda ToString jednoduše zavolá metody ToString třídy X a Y.

Dále jsem si vytvořili instanci této třídy a nadefinovali jsme si, že třída X bude typu DateTime a třída Y bude typu string.

Generické mohou být samozřejmě i metody a vlastnosti. Zde je metoda, která rozhodne zda-li jsou dva parametry stejného typu:


public bool Porovnej<T>(T val1, T val2)
{
      return val1.Equals(val2);
}

Generika přinesla významný přírůst výkonu hlavně při používání generických seznamů či slovníků. Proto doporučuji vždy pracovat s generickou variantou (pokud existuje).

Výjimky

Výjimky poskytují v .NET Frameworku způsob, jak reagovat na nečekané události. Uživatel např. zadá místo čísla text nebo soubor, který chceme otevřít, je využíván jiným procesem. To vše a mnoho víc zachycují výjimky.

Výjimky můžeme zachytávat blokem try-catch nebo try-catch-finally. Do bloku try vložíme „podezřelý“ kód – kód, ve kterém by mohlo dojít k nečekané události. Ihned za blokem try následuje blok catch, ve kterém napíšeme kód reagující na výjimečný stav vyvolaný v bloku try. Za blokem try může následovat blok finally, který se vykoná v každém případě.

Výjimky tvoří objekty třídy Exception nebo jeho potomci. V bloku catch dostaneme instanci třídy Exception nebo jeho potomka jako parametr. Třída obsahuje podrobné informace o výjimce.

Nyní si uvedeme příklad:


static void Main(string[] args)
{
        try
        {
                //Tento blok je pod kontrolou
                int cislo1 = Int32.Parse(Console.ReadLine());
                int cislo2 = Int32.Parse(Console.ReadLine());

                int vysledek = cislo1 / cislo2;

                Console.WriteLine(vysledek.ToString());
          }
          catch (DivideByZeroException e1)
          {
                //Tento blok se vykoná, když dojde k dělení nulou
                Console.WriteLine("Pokus o dělení nulou.");
          }
          catch (Exception e2)
          {
                //Tento blok se vykoná při jakékoliv jiné chybě
                Console.WriteLine("Jiná chyba: " + e2.Message);
          }
          finally
          {
                //Text se vypíše vždy
                Console.WriteLine("Tento text se vypíše vždy.");
          }
           
          Console.Read();
}

Tento kód přijme od uživatele dvě čísla, vydělí je a vypíše výsledek. Celý hlavní kód je v bloku try. Za ním následuje první blok catch s parametrem typu DivideByZeroException. Znamená to tedy, že první blok catch bude vykonán, jen když se vyvolá výjimka typu DivideByZeroException (dělení nulou). Druhý blok catch má parametr typu Exception, což je předek všech dalších výjimek (včetně DivideByZeroException). Tento se tedy vykoná při každém vyvolání výjimky, kromě dělení nulou, protože ten zachytí již první blok.

Můžete nadefinovat libovolné množství bloku catch. Pamatujte však, že nejprve nadefinujete „specializované“ bloky, protože nikdy se nevolá více než jeden blok catch.

Řekli jsme si, že všechny výjimky jsou odvozeny od třídy Exception. Můžeme si tedy nadefinovat vlastní výjimku:


class MyException : Exception
    {
        private DateTime time;

        public MyException(string message)
            : base(message)
        {
            time = DateTime.Now;
        }

        public DateTime Time
        {
            get { return time; }
        }
    }

Třída naší výjimky si navíc během volání konstruktoru uloží aktuální čas.

Výjimky můžeme vyvolávat sami. Vyvoláme tedy naši výjimku:


throw new MyException("Zpráva o chybě");

Nejdříve uvedeme klíčové slovo throw a pak založíme instanci příslušné výjimky.

Události

Události jsou základem tvorby uživatelských aplikací. Pomocí událostí komunikujeme s uživatelem, operačním systémem nebo s jinou částí aplikace. Pro nás události reprezentují způsob, jak komunikuje objekt s objektem.

Jako příklad si vytvoříme třídu s jedinou členskou proměnnou. Když ji změníme, vyvolá se událost s údaji, kdy k události došlo, a nová hodnota proměnné.

Pro obsluhu události musíme definovat delegáta, což je ukazatel na metodu. Pro událost potřebujeme dva parametry, a to objekt, který událost vyvolává, a data události. Pro jejich přenos si vytvoříme tuto třídu:


class MyEventArgs : EventArgs
    {
        private DateTime time;
        private string newValue;

        public MyEventArgs(DateTime time, string newValue)
        {
            this.time = time;
            this.newValue = newValue;
        }

        public DateTime Time
        {
            get { return time; }
        }

        public string NewValue
        {
            get { return newValue; }
        }
    }

Protože objekt vyvolávající událost může být cokoliv, používáme jako datový typ object.


public delegate void MyEventHandler(object sender, MyEventArgs e);

Dále nadefinujeme veřejnou proměnnou s modifikátorem event, která musí být stejného typu jako náš delegát. Tato proměnná představuje událost, jež má být vyvolána. Delegáta použijeme pro určení metody, která bude událost obsluhovat, a také jím určíme, jaké parametry mají být metodě předávány.

Nyní nadeklarujeme vlastní událost pomocí klíčového slova event.


public event MyEventHandler OnMyEventHandler;

Tím je určená vlastní událost. Důvod, proč je celý proces poněkud složitý, je, abychom mohli kontrolovat, zda je událost skutečně deklarována a přiřazena metoda. Pokud ne, událost nás nezajímá a nemusíme pro ni ani vytvářet kód. V následující metodě provedeme tuto kontrolu, inicializujeme instanci události a vyvoláme samotnou událost:


protected void OnMyEvent(object sender, DateTime time, string newValue)
{
	MyEventArgs e = new MyEventArgs(time, newValue);
	if(OnMyEventHanlder != null)
		OnMyEventHandler(sender, e);		
}

Zde je kompletní třída:


class MyClass
    {
        private string strValue;

        public delegate void MyEventHandler(object sender, MyEventArgs e);
        public event MyEventHandler OnMyEvent;

        public MyClass()
        {
            this.strValue = String.Empty;
        }

        public string Value
        {
            get { return strValue; }
            set
            {
                strValue = value;
                MyEvent(this, DateTime.Now, value);
            }
        }

        protected void MyEvent(object sender, DateTime time, string newValue)
        {
            MyEventArgs e = new MyEventArgs(time, newValue);
            if (OnMyEvent != null)
                OnMyEvent(sender, e);
        }
    }

Nyní si vytvoříme její instanci, přihlásíme se k odběru události a přiřadíme jí obslužnou metodu:


static void Main(string[] args)
{
     MyClass mc = new MyClass();
     mc.OnMyEvent += new MyClass.MyEventHandler(mc_OnMyEvent);

     for (int i = 0; i < 100; i++)
           mc.Value = "Hodnota " + i.ToString();
           
     Console.Read();
}

static void mc_OnMyEvent(object sender, MyEventArgs e)
{
      Console.WriteLine("Hodnota byla v " + e.Time.ToLongTimeString() + " změněna na " + e.NewValue);
}

Hodnotu změníme stokrát, takže přijmeme sto událostí.

Úkol číslo 3

Zadání

Vytvořte generickou třídu, která bude představovat jednoduchou implementaci funkce třídy List (jednoduchý seznam prvků, základní metody jako Add, Remove, Clear apod.). Interně však nesmíte využívat třídu List. Důležité bude, že každé volání metody Add a Remove vyvolá různé události, které budete v ukázkovém kódu nějak zpracovávat.

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor má rád programování, čtení, spaní a špagety. Nemá rád dechovku, rajskou.

Nové články

Obrázek ke článku Stavebnice umělé inteligence 1

Stavebnice umělé inteligence 1

Článek popisuje první část stavebnice umělé inteligence. Obsahuje lineární a plošnou optimalizaci.  Demo verzi je možné použít pro výuku i zájmovou činnost. Profesionální verze je určena pro vývojáře, kteří chtějí integrovat popsané moduly do svých systémů.

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý