Jazyk C# přednáška 01 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2014/2015
Přednáší Ing. Jan Hřídel (@h0nza) jan.hridel@upce.cz 466 037 178 V pochvalných i kritických tweetech z přednášky nezapomeňte zmínit @h0nza kancelář: 03 012 www.hridel.com
8 úrovní programátorů
Nejvyšší úroveň Váš kód vás přežije 1. mrtví programátoři No comment ;) The Art of Commputer Programming TeX OOP Windowing GUI Dijkstra Knuth Kay
Světově známí a vybudovali úspěšný byznys The real freedom zero 2. úspěšní programátoři Doom Quake RoR 37 Signals No comment ;) Carmack Hansson Gates
3. slavní programátoři Známí v programátorských kruzích Slavný je dobrý, ale úspěšný je lepší Většinou pracují pro velké a dobře známé korporace nebo jsou členy startup týmů
4. pracující programátoři Úspěšná kariéra softwarových vývojářů Výborné skills Nemají problém sehnat práci Firmy je berou všema deseti Ale co dál? Kam se odtud posunout?
5. průměrní programátoři Dost dobrý programátor, který ale není vynikající programátor A možná ani nikdy nebude Většinou chybí talent na kódování
6. amatérští programátoři Rádi kódují Ukazují své projekty Věnují programování hodně volného času Mohou se rychle přesunout do skupiny pracujících programátorů
7. neznámí programátoři Typický programátor Jan Kodér Obvykle pracuje v rámci velké anonymní společnosti Programování je jejich práce, ne celý jejich život
8. špatní programátoři Spadli do programátorské role ani nevědí jak. A to bez předchozích znalostí a zkušeností Vše, na co sáhnou, se stává utrpením pro ostatní spolupracovníky (programátory) možná s výjimkou jiných špatných programátorů.
Coding horror Bez rostoucího nadšení to bude zas jen rutina a práce
Zásady správného programování
Je to vždy vaše chyba! Pravidlo #1
Pravidlo #2 Nejlepší kód je žádný kód! http://goo.gl/87xhc
Nejlepší kód je žádný kód! Jako softwaroví vývojáři jste svým vlastním nejhorším nepřítelem. Pravidlo #2
Pravidlo #2 Nejlepší kód je žádný kód! Kód lze hodnotit z mnoha úhlů pohledů: Stručnost Plná funkcionalita Rychlost Čas strávený kódováním Robustnost Flexibilita if (s == String.Empty) vs. if (s == )
Pravidlo #3 Komentáře! Nejen co Nejen jak Ale i proč to write good comments you have to be a good writer
Dodržujte konvence! Pravidlo #4
Speciální případ
Pole Je to objekt! bool[] myarray; myarray = new bool[15]; myarray[4] = true; 5. prvek je true Skupina 15 prvků
Pole bool[] myarray = new bool[15]; Kombinace deklarace a inicializace
Jak velké je pole? Programmers.Length Pokud vrátí např. 7 znamená to, že v poli je 7 prvků s indexy 0-6.
Seřazení pole double[] somearray = { 4.0, 2.0, double.nan, 1.0, 5.0 }; foreach (double db in somearray) Console.WriteLine(db); Array.Sort(someArray); Console.WriteLine("\n\n"); foreach (double db in somearray) Console.WriteLine(db); Co bude na výstupu?
Seřazení pole bug fixed @.NET 4.0
OOP Objekt = instance třídy Objekt = Black Box Změna vnitřní implementace nesmí způsobit kolaps programu!
Keep your privates private! Je libo trochu soukromí? Síla zapouzdření! Vaše data mohou být private Napište metody, které budou bezpečně přistupovat k datům! No peeking!
Opakování private vs. public CIA agent realname alias password AgentGreeting() Enemy agent borscht vodka ContactComrades() OverthrowCapitalists()
Jak je to s protected? Opakování dědičnost
Statické členy? Opakování static
Opakování konstruktory [C#] Účelem je provést prvotní nastavení, společné pro všechny instance. nelze jej přímo zavolat to proběhne automaticky někdy těsně před vytvořením první instance nebo před použitím prvního statického členu okamžik volání nemá uživatel pod kontrolou
Co program vypíše? class Trida { public Trida() { Console.WriteLine("Instanční konstruktor"); } static Trida() { Console.WriteLine("Statický konstruktor"); } } //v Main() Trida o = new Trida();
Co program vypíše?
Opakování - destruktory [C#] Nemohou být definovány ve strukturách. Třída může mít pouze jeden destruktor. Destruktory nelze zavolat. Jsou vyvolávány automaticky. Nemají modifikátory ani parametry. Syntaxe: ~Trida(){}
Opakování - destruktory [C#] V C# objekty odstraňuje automatická správa paměti okamžik není přesně determinován Garbage Collector volá periodicky.net (cca každých 10 ms) Běh programu je zastaven Veškerá data, na která nevede odkaz, jsou z paměti odstraněna
Čistě statické třídy Obsahují pouze statické členy nelze vytvořit instanci přesněji: nemělo by jít vytvořit instanci. V.NET se jedná například o třídy Console nebo Math
Čistě statické třídy Jaké jsou možnosti zamezení vytvoření instance? Označit třídu jako static doporučeno Vytvořit privátní konstruktor
KONVENCE
Konvence pojmenování Pascal casing První písmeno každého slova velkým písmenem Nepoužívají se podtržítka DruhaMocnina Pro většinu identifikátorů Camel casing První písmeno malé; druhé a další slova začínají velkým písmenem. druhamocnina Parametry metod, lokální proměnné, soukromé datové složky třídy
Konvence pojmenování Prostory jmen Hlavní namespace název společnosti Vnořený namespace název projektu (aplikace) Názvy identifikátorů se uvádějí bez prefixu Kromě rozhrání s prefixem I, např. Idisposable Například název třídy by neměl být CDog nebo TDog, ale jen Dog
Konvence pojmenování Zkratky a akronymy Malými písmeny první znak však závisí na typu identifikátoru htmlcontrol pro soukromé složky HtmlControl pro ostatní složky Výjimka dvouznaké zkratky jsou velkými písmeny kromě těch, které jsou na začátku identifikátoru a mají být psány velbloudím stylem DBCommand veřejná složka dbcommand soukromá složka V.NET není pevně dodrženo (DbConnection)
Konvence pojmenování Více viz MSDN knihovna a téma Guidelines for Names http://goo.gl/179i1
Identifikátory Posloupnost písmen a číslic začínající písmenem. Písmeno jakýkoliv znak z UNICODE Rozlišují se malá a velká písmena Na začátek lze přidat znak @ @do vs. do Klíčové slovo
Klíčová slova http://goo.gl/8di7a Vždy malým písmenem
Deklarace proměnných Modifikátory(nep) typ identifikátor inicializace(nep) Modifikátory const volatile Typ typ proměnné Identifikátor jméno proměnné Inicializace inicializační část
Deklarace proměnných
Deklarace proměnných There are NO GLOBAL variables in C#
Deklarace proměnných Příklady int i, j = 11, k = 5; const int m = 10, n = 20; n je také konstanta
Deklarace proměnných Rozdíly oproti C++ Modifikátor const lze použít pro předdefinované (základní) datové typy. U referenčních typů (třídy) jej lze použít pouze tehdy, pokud je proměnná inicializována hodnotou null. Překladač nedovolí použít proměnnou jež nebyla inicializována. Ve vnořeném bloku nelze deklarovat proměnnou stejného jména jako v bloku nadřezeném.
Prostory jmen Rozdíly oproti C++ Mezi prostorem jmen a identifikátorem a mezi vnořeným a nadřazeným prostorem jmen se uvádí tečka. Pro složky prostorů jmen lze uvést přístupová práva.
Prostory jmen Deklarace namespace jméno { direktiva_using(nep) deklarace_složek } jméno název prostoru jmen direktiva_using direktiva using (viz dále) deklarace_složek deklarace datových typů (tříd, struktur, výčtových typů, )
Prostory jmen Deklarace vnořeného prostoru jmen Způsob 1 namespace Vnější { } namespace Vnitřní { } class X {}
Prostory jmen Deklarace vnořeného prostoru jmen Způsob 2 (v C++ neexistuje) namespace Vnější.Vnitřní { } class X {} V obou případech se mimo prostor jmen k X přistoupí způsobem Vnější.Vnitřní.X
Prostory jmen Přístupová práva public datový typ je veřejně přístupný, lze jej použít i v jiných sestaveních internal datový typ lze použít pouze v sestavení, ve kterém je deklarován internal je výchozí automaticky doplněno překladačem, pokud není specifikováno jinak
Direktiva using Syntaxe deklarace using jméno_prostoru_jmen; using alias = jméno_prostoru_jmen; using alias = jméno_typu; Direktiva using musí předcházet všem deklaracím v prostoru jmen.
Direktiva using Syntaxe deklarace using jméno_prostoru_jmen; Slouží k specifikaci prostoru jmen, jehož identifikátory se nemusí v programu klasifikovat jménem tohoto prostoru. Při použití using System; lze psát rovnou Console.Writeline(); protože Console je součástí prostoru jmen System. Nelze však psát File.Create( data.txt ); ani IO. File.Create( data.txt ); PROČ?
Direktiva using Syntaxe deklarace using jméno_prostoru_jmen; Slouží k specifikaci prostoru jmen, jehož identifikátory se nemusí v programu klasifikovat jménem tohoto prostoru. Při použití using System; lze psát rovnou Console.Writeline(); protože Console je součástí prostoru jmen System. Nelze však psát File.Create( data.txt ); ani IO. File.Create( data.txt ); PROČ? File leží v prostoru jmen System.IO, a ten není direktivou using zpřístupněn.
Direktiva using Syntaxe deklarace using alias = jméno_prostoru_jmen; Slouží k jinému pojmenování existujícího prostoru jmen. alias nové jméno prostoru jmen jméno_prostoru_jmen původní označení prostoru jmen using VV = Vnější.Vnitřní; Ke složce X pak lze přistoupit přes: VV.X.
Direktiva using Syntaxe deklarace using alias = jméno_typu; Slouží k nového jména pro daný typ. alias nové jméno typu jméno_typu původní označení typu using VVX = Vnější.Vnitřní.X; Nelze přejmenovat klíčové slovo: using cela = int; Lze však napsat: using cela = System.Int32; Obdoba typedef z C++ Typ int je jiné označení pro Int32 v prostoru jmen System
Operátor :: namespace alias qualifier Používá se ve spojení s klíčovým slovem global nebo ve spojení s aliasem prostoru jmen. global lze využít ke zpřístupnění složky z globálního prostoru jmen, která je zastíněna jiným jmenným prostorem. Obdoba unárního rozlišovacího operátoru :: z C++
Operátor :: namespace GlobalniProstorJmen { } class System { } class Program { } static void Main(string[] args) { } System.Console.WriteLine("Text"); global::system.console.writeline("text"); global::system.console.readkey();
Struktury V C# je rozdíl mezi strukturami a třídami o poznání větší než v C++. Syntaxe Modifikátor(nep) struct jméno specifikace_rozhraní(nep) { složky(nep) } ;(nep) modifikátor přístupová práva. jméno identifikátor datového typu dané struktury, který tato deklarace zavádí. specifikace_rozhraní rozhraní, která tato struktura implementuje (viz dále). složky seznam složek struktury (datové složky, metody, přetížené operátory, konstruktory, vlastnosti, události a vnořené typy).
Struktury Rozdíly mezi třídami a strukturami Struktury patří mezi hodnotové typy, třídy mezi referenční typy. Hodnotové typy se vytvářejí v zásobníku, referenční na haldě. Všechny struktury jsou potomkem třídy System.ValueType, která je odvozena od třídy object. V deklaraci nelze specifikovat předka a od struktury nelze odvodit potomka.
Struktury Rozdíly mezi třídami a strukturami Struktury nemohou mít destruktor. Struktury nemohou mít uživatelem definovaný konstruktor bez parametrů. Konstruktor struktury musí inicializovat všechny její datové složky. Překladač automaticky vytváří implicitní konstruktor, který inicializuje všechny datové složky na hodnotu 0, false nebo null.
Vytvoření instance Pomocí operátoru new Inicializací všech datových složek struktury struct Bod { public double x, y; Struktury public Bod(double x, double y) { } } this.x = x; this.y = y;
Struktury Vytvoření instance Bod a = new Bod(); Bod b = new Bod(30, 40); K jednotlivým datovým složkám lze přistoupit přes tečku (a.x, a.y, b.x, b.y). Jaké budou jejich hodnoty?
Struktury Vytvoření instance Bod a = new Bod(); Bod b = new Bod(30, 40); a.x = 0, a.y = 0 Identifikátory a, b nejsou ukazatelé. Operátor new u struktury nepředstavuje dynamickou alokaci paměti. Jedná se o instance. b.x = 30, b.y = 40
Struktury Bod c; Nevolá se konstruktor. c.x = 10; c.y = 20; Složky lze inicializovat samostatně int v = c.x + c.y; OK
Think, think, think Think about your users and their needs before you start building the code, and they ll be happy with the final product once you re done!