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

C# – 3. lekceC# – 3. lekce

 
Hledat
Moderní platforma pro vytvoření vašeho nového webu – Wix.com.
Nyní už můžete mít web zdarma.
Vytvořte si vlastní webové stránky. Snadno, rychle a levně přes Saywebpage.com
Vybavení pro Laser Game
Spuštěn Filmový magazín
Laser Game Brno
Laser Game Ostrava

C# – 3. lekce

Google       Google       4. 7. 2006       47 374×

  • Generika
  • Výjimky
  • Události

Reklama
Reklama

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 V přechodu na DVB-T2 tápou především senioři. Přeladit jim pomáhají vnoučata, zapojí se i stát

V přechodu na DVB-T2 tápou především senioři. Přeladit jim pomáhají vnoučata, zapojí se i stát

Už na konci měsíce může zůstat část Čechů bez televizního signálu. Vypínání stávající sítě začne již 27. listopadu v Praze a středních Čechách a do poloviny roku 2020 čeká přechod na nový standard pozemního digitálního televizního vysílání DVB-T2 celou republiku. K naladění nového televizního vysílání musí řada lidí nakoupit modernější zařízení, upravit antény nebo přejít na kabelové či internetové vysílání. 

Reklama
Reklama
Obrázek ke článku Zavádění Master Data Management v praxi

Zavádění Master Data Management v praxi

Předchozím článku jsme si vysvětlili, co jsou to Master Data, kdy je firma obvykle začíná řešit, v jakých krocích postupovat a jak nám může pomoci zvláštní nástroj pro evidenci Master dat. V tomto článku se podíváme na dvou příkladech, jak prakticky začít Master data řešit.

1. Nová Master Data, která potřebujeme někde spravovat
2. Zmapování existujících Master dat a určení jejich vlastníků

Obrázek ke článku 5 nesprávných důvodů, proč dělat vlastní mobilní aplikaci

5 nesprávných důvodů, proč dělat vlastní mobilní aplikaci

Myslíte si, že máte skvělý nápad na byznys apku a znáte všechno, co potřebujete? Možná vám vývoj software na míru rozmluví Vláďa Skoumal, z firmy studio SKOUMAL vyvijející mobilní aplikace 5.11. 2019 v 18:00 v Impact Hub Praha nebo tento jeho článek.


 

Obrázek ke článku Ericsson ConsumerLab Report: rozšířená realita je další úrovní gamingu

Ericsson ConsumerLab Report: rozšířená realita je další úrovní gamingu

Celkem 66 % uživatelů zajímá rozšířená realita v oblasti gamingu. Mezi nimi je i 35 % těch, kteří jinak hry nehrají.
Pro téměř 50 % respondentů by bylo zajímavé zapojení virtuální objektů do reálného světa. Objekty by zůstaly tam, kde je při hře „umístili“.
Až 43 % uživatelů láká využití rozšířené reality ve sportu

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