Horké novinky v jazyce C# 2.0 (3. díl)

V jazyce C# 2.0 lze využívat rozdílných přístupových práv pro akcesor get i set, v nezabezpečeném kódu lze deklarov...


V jazyce C# 2.0 lze využívat rozdílných přístupových práv pro akcesor get i
set, v nezabezpečeném kódu lze deklarovat a používat pole pevné délky.
V tomto závěrečném dílu našeho miniseriálu si představíme několik dalších
podstatných novinek, které se objevily v jazyce C# 2.0. Řeč přitom tentokrát
bude nejen o vlastním jazyce, ale i o několika zásadních vylepšeních vývojového
prostředí Visual Studio .Net 2005.

Statické třídy
Třídy, které obsahují pouze statické součásti, nazýváme statické. Vytvářet
instance takové třídy nemá smysl. Nově můžeme třídy explicitně označit
modifikátorem static jako statické, překladač pak vytváření instancí ani
nedovolí. Statické třídy mají všechny součásti statické, nemají konstruktor
(statický mít mohou), nelze z nich vytvářet instance a jsou zapečetěné (sealed).
V předchozích verzích jazyka C# bylo možno dosáhnout podobného chování také,
použití modifikátoru static je však jednodušší a bezpečnější (jeho používání
eliminuje lidské chyby).

Zástupná jména seskupení
Klíčové slovo extern doposud označovalo metody, které jsou v neřízeném kódu
(obvykle používáno ve spojení s DllImport). Nyní je možno použít extern také k
rozlišení seskupení, která obsahují stejné prvky (stejně pojmenované prostory
jmen i třídy, které jsou tedy navzájem nerozlišitelné).
Máme-li například dvě verze stejné komponenty, které chceme používat současně,
použijeme právě extern. Místo použití příkazu using pro klasické reference,
napíšeme toto:
extern alias Komponenta_verze1;
extern alias Komponenta_verze2;
Přiřazení těchto zástupných jmen konkrétním souborům se seskupeními provedeme
pomocí parametrů příkazové řádky překladače (grid.dll a grid20.dll jsou zde
jako příklady souborů se seskupeními):
/r:Komponenta_verze1=grid.dll
/r:Komponenta_verze2=grid20.dll

Odlišná přístupová práva
Vlastnosti (properties) dosud musely mít stejnou úroveň přístupových práv pro
akcesor get i set. Když jsme tedy chtěli, aby byla vlastnost zvnějšku jen pro
čtení, nesměla mít operaci set definovanou vůbec. Nyní je možno přiřadit
každému akcesoru jinou úroveň oprávnění.
public string Name {
get {
return name;
}
protected set {
name = value;
}
}
V ukázkovém kódu deklarujeme vlastnost jako veřejnou (public), potom však
uvedením modifikátoru private zamezujeme veřejný přístup k akcesoru set.
Při deklaraci odlišných přístupových práv pro get/set musíme dodržet některá
omezující pravidla. Vnitřní změna práv může být uvedena jen u jedné z operací
get/set a musí být vždy více restriktivní (v praxi tedy bude většinou využita
pro set). Při předefinování vlastnosti předka (pomocí override) ji musíme
deklarovat vždy s identickými oprávněními.
Na rozdíl od C ++ se implementace rozhraní v C# nepovažuje za dědění. Pokud je
vlastnost součástí rozhraní, které implementujeme, můžeme u akcesoru, který
není součástí implementovaného rozhraní, modifikátor oprávnění použít. Viz
následující příklad:
public interface MyInterface {
int MyProperty {
get;
}
}
public class MyClass : MyInterface {
public int MyProperty {
get {...}
protected set {...}
}
}
Akcesor set v ukázce nepatří do rozhraní MyInterface, ve třídě MyClass tedy
může být deklarován (i na vlastnosti MyProperty, která sama o sobě je součástí
rozhraní MyInterface) s omezením přístupu na private.

Kovariance a kontravariance
Již dříve zmíněná typová inference u generických typů není jediným novým prvkem
ulehčujícím nám od časté práce s explicitním přetypováním. Zvlášť u delegátů
není změna typu parametrů snadná, právě proto do jazyka C# přibyla kovariance a
kontravariance. (Tyto méně obvyklé výrazy možná znáte z geometrie, nyní se tedy
dostaly i do terminologie programování. Přitom kovarianci najdeme i v
nejnovějším standardu jazyka C++, současné překladače však tento prvek většinou
nepodporují.)
Kovariance umožňuje v delegátu použít metodu s návratovým typem, který je
potomkem návratového typu delegáta. Kontravariance naopak umožňuje v delegátu
použít metodu, jejíž parametry jsou předky parametrů delegáta. Obojí tedy stojí
na principu zastupitelnosti předka potomkem ve stromu dědičnosti. Pro větší
srozumitelnost si uveďme příklad.
class A {}
class B : A {}
class C : B {}
class Test {
delegate B Metoda(B param);
B MetodaA(A param) {
return null;
}
B MetodaB(B param) {
return null;
}
C MetodaC(B param) {
return null; }
public Test() {
Metoda ma = new Metoda(MetodaA);
Metoda mb = new Metoda(MetodaB);
Metoda mc = new Metoda(MetodaC);
}
}
Nejprve deklarujeme strom dědičnosti "C dědí B, B dědí A". Delegáta deklarujeme
se vstupním parametrem i návratovým typem B. Dále deklarujeme tři metody, které
ukazují všechny možnosti zastoupení.
1. MetodaB pasuje přímo, protože má odpovídající parametry.
2. (Kontravariance) MetodaA má vstupní parametr typu A, což je předek od B.
Delegát ma má vstupní parametr B. V okamžiku zavolání tohoto delegáta je předán
parametr typu B. Metoda v delegáta očekává typ A. Předaný parametr typu B je
tedy převeden na předka A.
3. (Kovariance) MetodaC má návratovou hodnotu typu C, což je potomek od B.
Delegát vrací hodnotu typu B. Při použití delegáta mc je zavolána MetodaC,
která vrací objekt typu C. Ten může být přetypován na typ B, což je potom
výsledná návratová hodnota delegáta mc.

Pole pevné délky
V nezabezpečeném (unsafe) kódu můžeme nyní deklarovat a používat pole pevné
délky, která jsou fyzicky uložena na místě deklarace (hodnotový typ, bez
reference) a neprovádí se pro ně kontrola přetečení bufferu apod.
unsafe public struct MyArray {
public fixed char path[256];
}
Zde jsme vytvořili strukturu MyArray obsahující proměnnou path, což je pole o
256 znacích. Toto skutečně fyzicky odpovídá poli například v C++, a představuje
tedy prvek, který v C# nebylo dříve možné nijak deklarovat. (Doposud bylo nutné
pro pole používat reference.) Tato konstrukce platí jen v unsafe kódu a je
vhodná například pro práci v COM.

Spřátelená seskupení
Chceme-li, aby seskupení (assembly) B mělo přístup do všech veřejných (public)
i neveřejných součástí seskupení A, pak v seskupení A použijeme následující
atribut:
[assembly:InternalsVisibleTo ("B", PublicKeyToken="...")]
Je to tedy obdoba friend známého již z C++, zde je však vyžadováno uvedení
hodnoty public key token seskupení, které chceme deklarovat jako spřátelené.
(Public key token je osmibajtová hodnota sloužící k rozlišení dvou stejně
pojmenovaných seskupení různých autorů.)

Nevypisování varování
Vypisování varovných hlášení (warnings) můžete nyní částečně ovlivnit přímo v
kódu, použitím nové direktivy (známé i z Visual C++):
#pragma warning disable 414,3021
#pragma warning restore 414,3021
První řádek v ukázce vypne vypisování hlášení číslo 414 a 3021, druhý řádek pak
vypisování hlášení opět obnoví. Zajímavé je, že pokud vypnete vypisování
varovných hlášení přímo v nastavení projektu, v kódu už jej nemůžete znovu
zapnout (možnosti jsou jen disable = zakázat a restore = obnovit původní
nastavení, možnost enable = povolit zde chybí). (A ještě poznámka: Vypínání
varovných hlášení samozřejmě není doporučeno.)

Vývojové prostředí
Kromě samotného jazyka je možno spatřit řadu velmi zajímavých novinek také ve
vývojovém prostředí Visual C#/Visual Studio .Net 2005, stejně jako v knihovně
základních tříd .Net Frameworku (BCL). Některé z nových součástí BCL jsou právě
důsledkem nových možností jazyka (generické kolekce apod.), jiné pak čistě
rozšiřují schopnosti vestavěných tříd pro snazší vytváření koncových aplikací
(řada novinek v ASP.Net apod.). Na závěr našeho seriálu uveďme alespoň některé
z nich.

Generické kolekce
Generické typy s sebou také přinesly nové generické kolekce, najdeme je v
prostoru jmen System.Collections.Generic. Je to částečně úprava původní sady
kolekcí System.Collections, částečně však jde o zcela nové prvky. Výhodou je,
že C# považuje každý typ a stejně pojmenovaný generický typ za dva rozdílné
typy, takže nové kolekce se obvykle jmenují (i používají) úplně stejně jako ty
původní, pouze umožňují lepší typovou kontrolu, a zajišťují tedy vyšší
bezpečnost kódu. Původní kolekce jsou samozřejmě nadále k dispozici, ale jejich
další používání se nedoporučuje (neboť nejsou silně typované).

Refactoring
Nyní můžeme velmi snadno provádět některé operace refactoringu, jako je změna
jmen, schování proměnné za vlastnost (property), rozdělení metody na dvě,
vytvoření rozhraní podle třídy, odstranění parametru metody nebo změna pořadí
parametrů metody. Všechny tyto operace fungují tak, že stávající kód bude po
jejich provedení i nadále použitelný, tj. například při změně pořadí parametrů
metody se provede tato úprava nejen v deklaraci, ale i ve všech známých
voláních této metody.

IntelliSense
Také funkcionalita IntelliSense byla rozšířena. (Pojmem IntelliSense označuje
Microsoft svůj systém pro podporu psaní zdrojového kódu, který během psaní
napovídá, jak má kód dále pokračovat. Funguje tak, že sleduje aktuální kontext
a nabízí vždy známé přípustné varianty.)
Seznam nabízených slov pro dokončení výrazu se snaží chovat inteligentně a
nabízet přednostně ta slova, se kterými často nebo obvykle pracujeme; seznamy
jsou rovněž více kontextově závislé.
Možnost automatického generování kódu dle kontextu byla značně rozšířena, což
velmi usnadňuje psaní delegátů pro obsluhu událostí k napsání dříve složitých
konstrukcí s delegáty stačí nyní napsat jméno události, kterou chceme delegátem
ošetřit. IntelliSense si naší snahy ihned všimne a umožní veškerý kód vytvořit
několikerým stiskem klávesy Tab.
Kromě zmíněné vestavěné podpory psaní delegátů máme také možnost vytvářet si
vlastní vzory kódu a použít je pro zrychlení psaní dalších často se opakujících
konstrukcí. Tato funkce se aktivuje velmi jednoduše: Napíšete definovanou
zkratku (slovo, heslo) a stisknete klávesu Tab.

Chytřejší ladění
Novinek se dočkal i debugger. Nyní nabízí rozšířenou (chytřejší) nápovědu vždy
s ohledem na aktuální kontext, což je zvláště poznat u nově přidaných popisů
všech systémových výjimek. V debuggeru je také řada dalších novinek
usnadňujících ladění, například je nyní rozlišován kód vlastní od kódu z
použitých knihoven či komponent. Chyby a výjimky vzniklé v cizím kódu tedy
debugger nesleduje a zaměřuje se pouze na chování našeho vlastního kódu.Vybrané
odkazy na web
n MSDN centrum nápovědy a dokumentace: msdn.microsoft.com
n MSDN Lab. laboratoř pro betaverze produktů apod.: lab.msdn.microsoft.com
n MSDN Magazine časopis serveru MSDN: msdn.microsoft.com/msdnmag/
n Visual Studio 2005 Beta Documentation: msdn2.microsoft.com









Komentáře
K tomuto článku není připojena žádná diskuze, nebo byla zakázána.