Diskuze: Programovací konvence a doporučení C#
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 28 zpráv z 28.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Používám vše, takže easy
Některá z těch pravidel se dají použít i v jiných jazycích, používají poměrně často var, některá běžná doporučení však chybí.
Na můj vkus mají moc roztahané try ... catch ... finally, které tím ztrácí přehlednost. Používám kompaktní formu i pro podmínky a cykly.
Co je na tom roztahaného? u try-catch / try-finally bloku tam ty blokové závorky musí být. Jedině, jak bys to mohl stáhnout je, že bys u té podmínky kde ničíš ten objekt, je nedáš ... Ale to už je na člověku, jestli je tam dává, i když je jeden příkaz.
Var pouzivaji v pripadech, kdy tim netrpi prehlednost (dokonce prave casto tu prehlednost zvysi, protoze se kod zkrati).
Me roztahane try-catch-finaly vyhovuje, jsou to preci jen vyjimky, takze by se mely stavat vyjimecne a jsem rad, kdyz je v kodu na prvni pohled vidim.
Mohlo by tam toho samozrejme byt vic, ale pro zacatek to alespon trochu pomoci muze.
Je to možné. Ale u žádného C# kódu jsem neviděl, že by dával ty blokové závorky už na konec řádku, je to spíše jeho zvyk z Javy. (Mačkám stejně úpravu kódu celkem často a to mi pokaždé upraví do té klasické varianty) Mimochodem, přijde mi to méně přehlednější, než ta klasická "roztahaná" varianta
Pro mne je obvyklý zápis try ... catch v kontextu odvozeném z toho webu např:
static string GetValueFromArray(string[] array, int index) {
Console.WriteLine("Začínám...");
try {
return array[index];
} catch (System.IndexOutOfRangeException ex) {
Console.WriteLine("Index is out of range: {0}", index);
throw;
} finally {
if (index == 0) {
Console.WriteLine("Warning: Index byl nulový");
}
}
}
Pro mne je ten zápis přehledný, proto ho používám. Na první pohled vidím, co k čemu patří, pro jistotu si to vždy nechám přerovnat editorem. Tím velice snadno najdu chybějící nebo přebývající závorky - odsazení se udělá jinak, než bych očekával.
Jo, vždyť říkám, takhle se píšou běžne závorky v Jave, tak jsi nato zvyklý. My .NETáři, jsme zvyklí na poněkud jiné věci. A editovat si VS kvůli try-catch bloku, který stejně používám jen na pár důležitých místech ... V C# to beru jako konvenci, že mají být složené závorky na samostatném řádku (když neberu příklad nastavování properties přímo u volání konstruktoru atd...) je to pro mě čitelnější a řekl bych že i pro ostatní
Je to jedna z konvencí otevírat závorky už na konci řádku s podmínkou.
Možná je to u mne i tím, že fonty v editoru mám nastavené na 14px a neviděl bych začátek či konec třídy, kterou právě edituji. Tím, že mám větší písmo, mi nevadí, že je text vertikálně zhuštěný.
try ... catch de facto stačí jen jedno v celé aplikaci, ale většinou chceš, aby se aplikace dokázala z drobných chyb rozumně zotavit.
Hlavně je to dost výkonově náročné, takže to používám velmi zřídka a jen tam, kde moc chybu nejde jinak ošetřit.
To je jen mýtus. Když výjimky použiješ správně, tak naopak šetří výkonem. Hlavně programátora.
Jak to může být výkonově náročné, když k výjimce dojde jen výjimečně?
To není mýtus. Ušetří ti to práci, to ano, ale aplikaci ti to opravdu zpomalí.
Já spíše narážím na úplné začátečníky, co si myslí, že narvat to do každé metody je nejlepší řešení a pak se diví, že je to jaksik pomalé.
Pokud někdo dělá i flow control pomocí výjimek, tak je to fakt špatně. Výjimka, ke které nedojde, však program vůbec nezpomalí. Naopak se zbavíš zbytečných podmínek, program se vyčistí a zrychlí.
Podmínkou je, že k těm výjimkám nedochází, alespoň ne moc často.
Jednoduše, ten kód se musí chovat jinak, protože musí zabránit té aplikaci, aby nespadla, když k té chybě dojde. Kdyby to bylo jak ty říkáš, bylo by to implementované explicitně už všude né ?
V C# když nějaký krátký kód hodíš do try-catch, a k chybě nedojde, tak je režie v řádech jednotek až několika málo desítek procent, pokud k výjimce dochází častěji, tak je režie v řádech desetisíců procent i víc.
Schválně jsem ti nato udělal úplně triviální test. http://www.itnetwork.cz/dev-lighter/211
Na linuxu to asi nespustíš, ale abys viděl výsledky tak tu máš i obrázek:
Je to na ticky procesoru. Abys viděl rozdíly v ms. Ofc záleží na tom, jestli je kritická pouze jedna operace nebo všechny ty části, ale obecně se vyhýbám try-catch bloku co nejvíce, když jsem začínal tak sem si to vychvaloval a teď když vidím, jak prasácky někdo ošetřuje vyjímky a myslí si, že je to správně, tak je mi akorát špatně
Zvláštní, mi jde
http://www.itnetwork.cz/…trycatch.png
Spustil jsem to i na Linuxu, ale trochu jsem to upravil. Počet cyklů jsem zestonásobil, abych měl přesnější výsledek a u B jsem přidal test validity (aby se srovnávalo srovnatelné). Místo převodu string->int jsem použil dělení, při kterém teoreticky může dojít k dělení nulou, ale dělitel jsem zvolil tak, aby nebyl nulový. Výsledky byly prakticky totožné.
Tvůj kód:
http://screenshot.cz/MVVYT/exc.png
Dokud k chybě nedochází vůbec nebo zcela výjimečně, tak má try-catch vliv malý (jednotky až desítky procent, podle velikosti a typu kódu), ale pokud by k němu mělo docházet častěji, třeba i jen u jednoho průchodu z 1000, tak už je to znát hodně a kód s výjimkami je několikrát pomalejší.
edit: ještě kód testování s výjimkami:
http://www.itnetwork.cz/dev-lighter/213
Jenže k výjimkám dochází méně často, než jeden průchod z 1000, takže měřit dobu jejich provádění je pro praktické účely zcela bezvýznamné.
To záleží na použití, jsou i lidé, co je dají do opakovaně volaného kódu i do místa, kde k nim dochází častěji
To je pak použití výjimek k řízení toku programu (např. k vyskakování z cyklu), což je nežádoucí. Je nutné se toho vyvarovat, aby k vyvolávání výjimek docházelo skutečně výjimečně.
Tuhle jsem někde na fóru viděl dotaz, že nějaký nešťastník nemohl najít chybu ve svém programu, nefungoval jak měl. Měl tam 3 bloky try..catch a ve všech třech měl větev "catch" prázdnou. Takovým obvykle není pomoci...
Obvykle se obálka try..catch nachází mimo cyklus a tím, že se ušetří jeden validační test uvnitř cyklu, se ušetří i nějaký čas. Vždycky to záleží na tom, jakým způsobem ty výjimky použiješ. Nelze paušálně tvrdit, že jsou rychlejší nebo pomalejší.
V desnej dobe byvaju vynimky dizajnovane tak ze spracovanie chyb je oddelene od hlavneho toku programu (tzv. Zero cost exception). Takze ak nenastane vynimka tak program moze byt teoreticky aj rychlejsi ako testovanie cez if else switch... Ak nastane vynimka, tak sa presunie tok programu a zacne sa postupne spracovavat vynimka. Samotne spracovanie vynimky je ovela pomalsie, preto sa vynimky maju pouzivat na "vynimocne" udalosti ako napr fatalne chyby. Kedysi boli vynimky implementovane cez setjmp/longjmp a preto maju relativne zlu povest. Dnes sa vecsinou pouzivaju vynimky podla DWARF standartu a vo windowse SEH (ms musi mat vzdy nieco co je nekompatibilne so ostatnymi...)
Zobrazeno 28 zpráv z 28.