Jazyk C# přednáška 01
Fakulta elektrotechniky a informatiky Univerzita Pardubice 2014/2015
Přednáší • Ing. Jan Hřídel (@h0nza) • • • •
[email protected] 466 037 178 kancelář: 03 012 www.hridel.com
V pochvalných i kritických tweetech z přednášky nezapomeňte zmínit @h0nza
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
Dijkstra
Knuth
OOP Windowing GUI
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
Carmack
Hansson
No comment ;)
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í
Pravidlo #1
• Je to vždy vaše chyba!
Pravidlo #2
• Nejlepší kód je „žádný“ kód! http://goo.gl/87XHC
Pravidlo #2
• Nejlepší kód je „žádný“ kód! •
Jako softwaroví vývojáři jste svým vlastním nejhorším nepřítelem.
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; Skupina 15 prvků 5. prvek je true
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()
Opakování – dědičnost • Jak je to s protected?
Opakování – static
• Statické členy?
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
•
V .NET není pevně dodrženo (DbConnection)
• DBCommand – veřejná složka • dbCommand – soukromá složka
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 •
typ identifikátor inicializace(nep)
Modifikátory
• •
• • •
(nep)
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:
•
•
Obdoba typedef z C++
using cela = int;
Lze však napsat:
•
using cela = System.Int32;
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
Struktury
struct Bod { public double x, y;
public Bod(double x, double y) { this.x = x;
this.y = y; } }
Struktury • Vytvoření instance •
Bod a = new Bod();
K jednotlivým datovým složkám lze přistoupit přes tečku (a.x, a.y, b.x, b.y).
•
Bod b = new Bod(30, 40);
Jaké budou jejich hodnoty?
Struktury Identifikátory a, b nejsou ukazatelé.
• Vytvoření instance •
Bod a = new Bod();
a.x = 0, a.y = 0
•
Operátor new u struktury nepředstavuje dynamickou alokaci paměti.
Bod b = new Bod(30, 40);
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!