Professional Documents
Culture Documents
Warsztat
programisty
Autor: Adrian Kingsley-Hughes, Kathie Kingsley-Hughes
Tumaczenie:Wojciech Demski
ISBN: 978-83-246-1065-5
Tytu oryginau: C# 2005 Programmers Reference
Format: B5, stron: 392
oprawa twarda
Wydawnictwo Helion
ul. Kociuszki 1c
44-100 Gliwice
tel. 032 230 98 63
e-mail: helion@helion.pl
Narzdzia programistyczne
Struktura jzyka C#
Typy danych
Wyraenia i instrukcje
Przestrzenie nazw
Klasy i obiekty
Typy wyliczeniowe
Obsuga wyjtkw
Typy generyczne
Spis treci
O autorach .................................................................................................................................................. 15
Wprowadzenie ........................................................................................................................................... 17
Rozdzia 1. Czym jest C#? ..........................................................................................................................23
Nazwa ......................................................................................................................... 23
Oglny rzut oka na C# .................................................................................................. 23
Historia .................................................................................................................. 24
C# i CLR ................................................................................................................ 24
Wzmianka o .NET .................................................................................................... 25
Standardy ............................................................................................................... 25
Inne implementacje ................................................................................................. 25
Przykadowy kod C# ...................................................................................................... 26
Korzyci z nauki programowania w C# ............................................................................ 28
Podsumowanie ............................................................................................................ 28
Spis treci
Spis treci
10
Spis treci
11
12
Spis treci
13
Struktura jzyka C#
Aby pisa dobre programy w C#, naley w peni zrozumie struktur tego jzyka. W rozdziale tym omwimy jzykow, czyli leksykaln struktur programw napisanych w C#.
Oto kolejno, w jakiej bdziemy przedstawia tematy:
Q
Programy C#
Gramatyka
Zakoczenia wierszy
Komentarze
Biae znaki
Tokeny
Sowa kluczowe
Dyrektywy
Programy C#
Kady program C# tworzony jest z jednego bd wielu plikw rdowych. Te pliki, zwane te jednostkami kompilacji, mog by odrbnymi plikami tekstowymi lub te plikami
zawartymi wewntrz zintegrowanego rodowiska IDE (ang. Integrated Development Environment), jak Visual Studio.
Jednostki kompilacyjne zawieraj uporzdkowane sekwencje znakw Unicode (okrne
okrelenie tekstu) i aby zapewni maksymaln przenaszalno, wszystkie pliki rdowe
powinny by zakodowane w standardzie UTF-8. Korzystajc z prostego edytora tekstowego (jakim jest Notatnik) lub rodowiska programistycznego specyficznego dla C#, moemy
mie pewno, e kod otrzyma poprawny format.
58
Atrybut jest obiektem reprezentujcym dane, ktre zamierzamy powiza z elementem programu, podczas gdy element, z ktrym wiemy ten atrybut, nazywamy adresatem atrybutu.
Wszystkie elementy jednostki kompilacji peni okrelon rol:
Q
Identyfikatory
Sowa kluczowe
Literay
Operatory
Separatory
59
Gramatyka
W jzyku C# stosuje si gramatyk dwojakiego rodzaju:
Q
Zakoczenia wierszy
Biae znaki
Komentarze
Tokeny
Dyrektywy preprocesora
Dwuznacznoci gramatyczne
W kadym jzyku programowania mona napotka pewne dwuznacznoci. Dla przykadu
rozwamy takie oto wyraenie:
F(X<Y, Z>(5));
60
==
!=
lista argumentw typu definiuje cz prostej nazwy, dostp do skadowej lub dostp do
wskanika poprzedzajcego i wszystkie dalsze opcje s odrzucane.
Jeli nastpnym tokenem jest token, ktrego nie ma na powyszym wykazie, to lista argumentw typu nie definiuje czci nazwy, dostpu do skadowej ani dostpu do wskanika
poprzedzajcego.
Powysza regua nie odnosi si do parsowania listy argumentw typu w przestrzeni
nazw czy nazwach typw.
Wracajc do naszego wczeniejszego, do niejednoznacznego przykadu:
F(X<Y, Z>(5));
Zgodnie z reguami, ktre wymienilimy wczeniej, zapis ten zostanie zinterpretowany jako
wywoanie F z jednym argumentem, ktry stanowi wywoanie metody generycznej X, o dwch
argumentach typw i jednym argumencie zwykym.
Oto dwa nastpne przykady wyrae, ktre zostan zinterpretowane jako wywoanie F z dwoma argumentami:
F(X<Y, Z>5);
F((X<Y, Z>>5);
Unarny operator +
61
Analiza leksykalna
Kady plik rdowy programu C# musi by zgodny z nastpujcym gramatycznym wzorcem leksykalnym:
wejcie:
wejcie-sekcjaopcj
wejcie-sekcja:
wejcie-sekcja-cz
wejcie-sekcja wejcie-sekcja-cz
wejcie-sekcja-cz:
elementy wejcioweopcj
dyrektywa-pp
elementy-wejciowe
element-wejciowy
elementy-wejciowe
nowy-wiersz
wejcie-element
wejcie-element:
biay znak
komentarz
token
Zakoczenia wierszy
Biae znaki
Komentarze
Tokeny
Dyrektywy preprocesora
Spord tych elementw jedynie tokeny maj znaczenie z punktu widzenia gramatyki syntaktycznej dowolnego programu C# (z wyjtkiem sytuacji, gdy token > wystpuje cznie
z innym tokenem, tworzc z nim operator). Kiedy kompilator dokonuje leksykalnego przetwarzania jednostki kompilacji, to traktuje plik jako seri tokenw, ktre stanowi wejcie
dla pniejszego przetwarzania syntaktycznego. Zakoczenia wierszy, biae znaki i komentarze oddzielajce token y s elementami wycznie leksykalnymi i nie maj adnego wpywu na skadni programu C#. Podobnie dyrektywy preprocesora su tylko do omijania
fragmentw kodu w pliku rdowym i jeli chodzi o skadni, take nie maj znaczenia.
Zawsze kiedy w wyniku przetwarzania leksykalnego moliwe jest uzyskanie kilku wynikw, procesor leksykalny pobiera najduszy poprawny element leksykalny. Na przykad,
jeli kompilator napotyka nastpujc sekwencj znakw:
//
przetwarza je i interpretuje jako pocztek wiersza komentarza, a nie dwa wystpienia tokena / (w takim przypadku nie oznaczayby one pocztku komentarza). Podobnie dzieje si,
kiedy napotkana zostaje sekwencja:
!=
62
Zakoczenia wierszy
Zakoczenie wiersza suy do dzielenia sekwencji znakw w pliku rdowym C# na osobne wiersze.
Istnieje szereg rnych zakocze wierszy:
Q
Aby zachowa wysoki poziom kompatybilnoci z rnymi narzdziami do edycji kodu rdowego, ktre umieszczaj znaki zakoczenia pliku, i zapewni, e pliki rdowe C# bd
odczytywane jako sekwencja poprawnie zakoczonych wierszy, s one poddawane dwm
przeksztaceniom:
Q
Jeli rdowy plik C# nie jest pusty i jeli jego ostatnim znakiem nie jest znak
powrotu karetki (U+000D), wysunicia wiersza (U+000A), przejcia do nastpnego
wiersza (U+2085), separatora wiersza (U+2028) lub separatora akapitu (U+2029),
to na kocu pliku umieszczony zostaje znak powrotu karetki (U+000D).
Komentarze
C# obsuguje dwa rodzaje komentarzy w plikach rdowych:
Q
Komentarze wyodrbnione
Komentarze jednowierszowe
Komentarze wyodrbnione
Komentarz wyodrbniony zawsze rozpoczyna si znakami /*, a koczy znakami */.
Komentarz taki moe zajmowa fragment wiersza:
63
Jeden wiersz:
/* Program testowy Hello World */
class Test
{
static void Main() {
System.Console.WriteLine("Hello, World!");
}
}
64
Komentarze jednowierszowe
Komentarze jednowierszowe to jak sama nazwa wskazuje, komentarze zawarte w jednym
wierszu. Zaczynaj si od znakw // i biegn do koca wiersza:
class Test
{
static void Main() {
System.Console.WriteLine("Hello, World!"); // wywietla "Hello, World!"
}
}
Wewntrz kodu mona umieci tyle komentarzy jednowierszowych, ile jest konieczne:
// wywietla "Hello, World!"
class Test
{
static void Main(){
System.Console.WriteLine("Hello, World!"); // wywietla "Hello, World!"
}
}
Nie wolno jednak umieszcza komentarzy jednowierszowych wewntrz wyrae. Oto przykad niepoprawnego wpisania komentarza:
// wywietla "Hello, World!"
class Test
{
65
Zagniedanie komentarzy
Nie mona zagnieda komentarzy. Trzeba tego unika w imi czytelnoci kodu:
// /* Niewaciwe zagniedenie komentarza */
/* // Niewaciwe zagniedenie komentarza */
Biae znaki
Biaymi znakami s spacje, znaki tabulacji poziomej i pionowej, jak rwnie znak przesunicia strony.
Tokeny
Wyrniamy pi rodzajw tokenw:
Q
Identyfikatory
Sowa kluczowe
Literay
Operatory
Znaki interpunkcyjne
Biae znaki i komentarze nie s traktowane jak tokeny, a jedynie jako ich separatory.
66
Identyfikatorach
Literaach znakowych
Identyfikatory
Reguy rzdzce uyciem identyfikatorw s dokadnie takie same jak zalecane w Unicode
Standard Annex 15 (http://www.unicode.org/reports/tr15/), z nastpujcymi wyjtkami:
Q
67
dostpny-identyfikator:
identyfikator-lub-sowo-kluczowe, ktre nie jest sowem kluczowym
identyfikator-lub-sowo-kluczowe:
znak-pocztkowy-identyfikatora kolejne-znaki-identyfikatoraopcji
znak-pocztkowy-identyfikatora:
znak-litera
_ (znak podkrelenia U+005F)
kolejne-znaki-identyfikatora:
kolejny-znak-identyfikatora
kolejne-znaki-identyfikatora
kolejny-znak-identyfikatora
kolejny-znak-identyfikatora:
znak-litera
znak-cyfra-dziesitna
znak-cznik
znak-czcy
znak-formatujcy
znak-litera:
znak Unicode klasy Lu, Ll, Lt, Lm, Lo lub Nl
sekwencja-specjalna-Unicode reprezentujca znak klasy Lu, Ll, Lt, Lm, Lo lub Nl
znak-czcy:
znak Unicode klasy Mn lub Mc
sekwencja-specjalna-Unicode reprezentujca znak klasy Mn lub Mc
znak-cyfra-dziesitna:
znak Unicode klasy Nd
sekwencja-specjalna-Unicode reprezentujca znak klasy Nd
znak-cznik:
znak Unicode klasy Pc
sekwencja-specjalna-Unicode reprezentujca znak klasy Pc
znak-formatujcy:
znak Unicode klasy Cf
sekwencja-specjalna-Unicode reprezentujca znak klasy Cf
identyfikatorl
_identyfikator
@private
Dwa identyfikatory uznawane s za identyczne, jeli po wymienionych niej przeksztaceniach (dokonanych w opisanej kolejnoci) staj si takie same:
Q
68
Sowa kluczowe
Sowo kluczowe podobne jest do identyfikatora, z t rnic, e jest zastrzeone. Sowa kluczowe mog by identyfikatorami tylko wwczas, kiedy poprzedza je prefiks @.
Oto lista sw kluczowych w C#:
abstract
as
base
bool
break
byte
case
catch
char
checked
class
const
continue
decimal
default
delegate
do
double
else
enum
event
explicit
extern
false
finally
fixed
float
for
foreach
goto
if
implicit
in
int
interface
internal
is
lock
long
namespace
new
null
object
operator
out
override
params
private
protected
public
readonly
ref
return
sbyte
sealed
short
sizeof
stackalloc
static
string
struct
switch
this
throw
true
try
typeof
uint
ulong
unchecked
unsafe
ushort
using
virtual
void
volatile
while
Literay
Zadanie literaw jest bardzo proste: reprezentuj one wartoci w kodzie rdowym.
Istnieje szereg rnych literaw.
Literay logiczne
W tej grupie wyrniamy dwa literay:
Q
true
false
Literay cakowitoliczbowe
Literay cakowitoliczbowe stosuje si do zapisywania wartoci nastpujcych typw:
Q
int
uint
long
ulong
Wartoci dziesitne
Wartoci szesnastkowe
Jeli litera cakowitoliczbowy zapisany jest bez sufiksu, to jest to litera typu:
int
uint
long
ulong
Jeli litera cakowitoliczbowy zapisany jest z sufiksem U lub u, to jest to litera typu:
uint
ulong
Jeli litera cakowitoliczbowy zapisany jest z sufiksem L lub l, to jest to litera typu:
long
ulong
Jeeli litera cakowitoliczbowy zapisany jest z sufiksem UL, uL, Ul, LU, lU lub Lu,
to jest to litera typu:
ulong
69
70
Literay rzeczywiste
Literay rzeczywiste su do zapisywania wartoci nastpujcych typw:
Q
float
double
decimal
Jeli sufiks nie zosta uyty, warto domylnie przyjmuje typ double.
Literay znakowe
Litera znakowy reprezentuje pojedyncze znaki pomidzy apostrofami, jak 'x'.
Ponisza tabela wymienia specjalne sekwencje znakw w C#:
Sekwencja znakw
Nazwa znaku
Unicode
\'
Apostrof
0x0027
\"
Cudzysw
0x0022
\\
0x005C
\a
Alarm
0x0007
\b
Znak cofania
0x0008
\f
Wysuw strony
0x000C
\n
Nowy wiersz
0x000A
\0
Null
0x0000
\r
Powrt karetki
0x000D
\t
Tabulacja pozioma
0x0009
\v
Tabulacja pionowa
0x000B
71
prosta-sekwencja-specjalna
heksadecymalna-sekwencja-specjalna
sekwencja-specjalna-Unicode
pojedynczy-znak:
Dowolny znak oprcz ' (U+0027), \ (U+005C) oraz znaku nowego wiersza
prosta-sekwencja-specjalna: jedna z
\' \" \\ \0 \a \b \f \n \r \t \v
szesnastkowa-sekwencja-specjalna:
\x cyfra-hex cyfra-hexopcj cyfra-hexopcj
cyfra-hexopcj
Znak nastpujcy po lewym ukoniku (\) musi by jednym ze znakw wymienionych w powyszej tabeli, w przeciwnym razie podczas kompilacji pojawi si bd.
Literay acuchowe
W jzyku C# zaimplementowano obsug dwch rodzajw literaw acuchowych:
Q
Zwyky litera acuchowy jest acuchem skadajcym si z zera lub wicej znakw zapisanych pomidzy cudzysowami. Literay tego rodzaju mog zawiera zarwno proste, jak
i szesnastkowe sekwencje specjalne, jak rwnie sekwencje Unicode.
string = "Hello, World!";
Dosowny litera acuchowy skada si ze znaku @ poprzedzajcego cudzysw, a nastpnie zero lub wicej znakw, i koczy si cudzysowem.
string = @"Hello, World!";
Literay puste
Na temat literaw pustych nie da si powiedzie zbyt wiele po prostu s one puste.
72
&
>
<
??
::
++
--
&&
||
->
==
!=
<=
>=
+=
-=
*=
/=
%=
&=
|=
^=
<<
<<=
> > (przesunicie w prawo, zoone z dwch tokenw: > oraz >)
73
Dyrektywy preprocesora
Dyrektywy preprocesora zapewniaj kodowi C# ogromn funkcjonalno. Dziki nim mona:
Q
Raportowa bdy.
symboli kompilacyjnych.
Q
74
Dyrektywy preprocesora nie s tokenami C# i nie stanowi elementu gramatyki syntaktycznej tego jzyka.
Kada dyrektywa preprocesora musi by wpisana w nowym wierszu kodu rdowego. Oprcz
tego kada z nich musi zaczyna si od znaku #, po ktrym nastpuje nazwa dyrektywy.
Warto pamita, e jakkolwiek przed znakiem #, a take pomidzy nim i nazw
dyrektywy, moe znajdowa si biay znak, to jednak nie jest to zalecane, gdy
utrudnia czytanie kodu.
Wiersz kodu zawierajcy dyrektyw #define, #undef, #if, #elif, #else, #endif lub #line
moe koczy si jednowierszowym komentarzem. W wierszach takich nie dopuszcza si
jednak umieszczania komentarzy wyodrbnionych.
Dyrektywy preprocesora mog mie ogromny wpyw na wyniki kompilacji rdowego
kodu C#.
Na przykad skompilowanie nastpujcego kodu:
#define A
#undef B
#define C
#undef B
class D
{
#if A
void E() {}
#else
void F() {}
#endif
#if B
void G() {}
#else
void H() {}
#endif
#if C
void I() {}
#else
void J() {}
75
#endif
#if D
void K() {}
#else
void L() {}
#endif
}
E()
H()
I()
L()
{}
{}
{}
{}
Zdefiniowany
Niezdefiniowany
Pocztkowo symbol przyjmuje stan niezdefiniowany i zachowuje go do czasu jawnego zdefiniowania. Napotkana dyrektywa #define pozostaje w tym stanie do czasu napotkania dyrektywy #undef lub do chwili osignicia koca pliku rdowego.
Wyraenia preprocesora
Wyraenia preprocesora mog by zawarte w dyrektywach #if oraz #elif. W wyraeniach
tych mona stosowa nastpujce operatory:
Q
==
!=
&&
||
76
Dyrektywy deklaracji
Dyrektywy deklaracji su do definiowania i uniewaniania symboli kompilacji warunkowej.
Przetworzenie dyrektywy #define skutkuje zdefiniowaniem symbolu kompilacji warunkowej, obowizujcego od wiersza nastpujcego bezporednio po dyrektywie.
Przetworzenie dyrektywy #undef powoduje uniewanienie symbolu kompilacji warunkowej, obowizujce od wiersza nastpujcego bezporednio po dyrektywie.
Dyrektywa #define moe by te uyta do przedefiniowania symbolu, ktry zosta zdefiniowany wczeniej, bez koniecznoci uprzedniego stosowania dyrektywy #undef do tego symbolu.
Dyrektywy diagnostyczne
Zadaniem dyrektyw diagnostycznych jest generowanie komunikatw o bdach i ostrzeeniach,
ktre raportowane s w taki sam sposb jak inne bdy i ostrzeenia w czasie kompilacji.
Zarwno:
#warning Sprawd kod!
jak i:
#error Bd kodu w tym miejscu
77
#endregion
#endif
Dyrektywy #line
Dyrektywy #line su do zmiany numerw wierszy i nazw plikw rdowych zwracanych
przez kompilator, na przykad w komunikatach o bdach i w ostrzeeniach.
Jeli w kodzie rdowym nie ma adnej dyrektywy #line, wwczas kompilator zwraca rzeczywiste numery wierszy i nazwy plikw rdowych.
Dyrektywy #pragma
Dyrektywa #pragma jest dyrektyw preprocesora, przy uyciu ktrej dostarcza si kompilatorowi informacji kontekstowych.
Oto przykady sytuacji, w ktrych dyrektywy te bywaj uyteczne:
Q
Podsumowanie
W rozdziale tym omawialimy leksykaln struktur C#, zwracajc szczegln uwag na
programy C#, gramatyk, zakoczenia wierszy, komentarze, tokeny, sowa kluczowe i dyrektywy. Majc na wzgldzie reguy gramatyki leksykalnej C#, programista moe oszczdzi sobie wiele pracy i przez zmniejszenie liczby bdw skrci czas debugowania.
W rozdziale 5. omwione zostan rozmaite koncepcje jzyka C#.