141 77 13MB
Polish Pages 6 Year 2012
SKŁADNIA JĘZYKA Podstawowe typy danych (wybrane) Pomzsze typy są typami C#; w większości ich nazwy pokrywają się z nazwami typów .NET (z tą różnicą, iż typy w .NET zaczynają się od wielkiej litery, np. Byte ). b y te (I bajt) — typcalkowitoliczbowy, zakres: od 0 do 255. sh o rt (2 bajty) — typ calkowitoliczbowy, zakres; od -32 768 do 32 767. i nt (4 bajty) — typ calkowitoliczbowy, zakres: od-2 147 483 648 do 2 (47483 647. 1 o ng (8 bajtów) — typ calkowitoliczbowy, zakres: od-9 223 372 036 854 775 808 do 9 223 372 036 854 775 807. f lo a t (4 bajty)— n azw aw .N ETSingle.Typ zmiennoprzecinkowy pojedynczej precyzji (do 7 cyfr znaczących). Zakres: od ±l.5e-4S do ±3.4e38. Wymagane jest dołączenie za wartością tego typu litery F, np. 3.14F. d o u b l e (8 bajtów) — typ zmiennoprzecinkowy podwójnej precyzji (do 15-16 cyfr znaczących), Zakres: od ±5.0e-324 do ±/.7e308. Jest to domyślny typ dla liczb zmiennoprzecinkowych, nie wymaga sufiksu. d e c i ma 1 (16 bajtów) — typ zmiennoprzecinkowy. Używany do operacji wymagających dużych liczb i dużego bezpieczeństwa przy modyfikacji zmiennych. Zakres: od ±/.0e-28 do ....................... litery m, np. 9.5m. ch ar (2 bajty) — typ znakowy. Służy do przechowywania pojedynczych znaków Unicode. Znaki są zapisywane w apostrofach, np. ' a ' . b ool (I bajt) — typ logiczny. Zmienne tego typu przechowują wartość logiczną— prawda (tru e ) lub fałsz ( f a l se). Ponadto dostępne są typy u i n t, u s h o r t i u 1 ong (liczby bez znaków), które mają dwukrotnie większy zakres liczb dodatnich od swoich tradycyjnych odpowiedników (np. u s h o r t - o d Odo 65 535).
Komentarze Komentarze pozwalają na dodanie uwag do kodu. Nie są one przetwarzane przez kompilator. Wyróżniamy dwa rodzaje komentarzy: I I komentarz wjednej linijce
I* Komentarz iv dwóch i większej liczbie linijek
V
Instrukcje Instrukcją jest każda czynność wykonywana w ramach programu. Zazwyczaj kończy się średnikiem:
instrukcja-, Pojedynczą instrukcję można zastąpić blokiem instrukcji, czyli ciągiem pojedynczych instrukcji ujętych w nawiasy klamrowe:
in s t r u k c ja l ; instru kcja 2 \ in s tru k c ja 3 ; )
Zmienne Zmienne deklaruje się, umieszczając nazwę typu oraz nazwę zmiennej. Każdą deklarację (podobnie jak inne instrukcje języka C#) kończy się średnikiem.
Instrukcja sw i t c h (wyboru) zastępuje szereg instrukcji i f, jeśli wszystkie odnoszą się do tej samej zmiennej.
• przypisania, • inne. Operatory arytmetyczne znamy z życia codziennego. Są to: • + (dodawanie); • - (odejmowanie); • * (mnożenie); • / (dzielenie); • % (modulo, reszta z dzielenia); • ++ (zwiększa wartość zmiennej o jeden); • - - (zmniejsza wartość zmiennej o jeden).
Stałe Deklarowanie stałych odbywa się w ten sam sposób, co deklarowanie i inicjalizowanie zmiennych, z wyjątkiem dodania słowa kluczowego c o n s t na początku instrukcji: co n st in t lic z b a = 3; Wartości stałej nie można zmieniać w trakcie działania programu.
Operatory Za pomoq operatora można wykonywać operacje na wyrażeniach (zmiennych bądź wartościach stałych). Operatory dzielimy na: o arytmetyczne, » logiczne, o bitowe, o relacji,
(w)
ca se 0: // instrukcje b re a k ; c a s e 1: U kolejne instrukcje
b re a k ; d e f a u lt :
Dzielenie dwóch liczb całkowitych (np. typu i nt) zwraca wynik całkowity (np. 5/3 = I). jeśli chcemy uzyskać wynik realny, trzeba np. dodać do licznika lub mianownika wartość pu zmiennoprzecinkowego (najszybciej 0.0), np.: wyrażenie typu zmiennopi ( 5 + 0 . 0 ) /33 zwróci wynik 1,86666666666667 (w przybliżeniu).
I I inne instrukcje
b re a k ; } Zmienna w może być typu calkowitoliczbowego, znakowego lub być łańcuchem znaków. Instrukcje wewnątrz danej klauzuli c a s e zostaną wykonane, jeśli zmienna w będzie miała wartość określoną w klauzuli. Każda instrukcja c a s e musi kończyć się instrukcją b r e a k ;. Przeciwnie niż w języku C + + nie jest możliwe „spadanie" między poszczególnymi instrukcjami ca se . Jeśli żaden z określonych warunków nie zostanie spełniony, wykonywane są instrukcje z sekcji d e f a u lt . Kolejną często wykorzystywaną konstrukcją są pętle. Pętla to blok instrukcji kodu, który jest wykonywany cyklicznie. C # oferuje trzy rodzaje pętli: f o r , whi 1 e, d o . .w h i 1 e. Pętla f o r jest używana, kiedy znamy liczbę przebiegów pętli.
Operatory logiczne zwracają wartość typu b oo l ean, uzależniając ją od podanych operandów. (w l && w2) — zwróci t r u e , jeśli w l i w2 mają wartość t r u e (suma logiczna). (w l || w2) — zwróci t r u e , jeśli w l lub w2 ma wartość t r u e (alternatywa logiczna). ( l w i ) — zwróci t r u e , jeśli w l ma wartość f a l se (negacja logiczna). (w l ~ w2) — zwróci tr u e , jeśli tylko jedna z wartości ma wartość t r u e (rozłączna alternatywa logiczna). Operatory bitowe wykonują operacje na liczbach w postaci bitowej (system dwójkowy). Można je też wykorzystywać zamiast analogicznych operatorów logicznych. (w l & w 2 )— sumabitowa. (w l | w 2 )— alternatywabitowa. (w l A w2) — rozłącznaalternatywa bitowa. ( -w 1) — negacja bitowa (nie może być zastosowana do wartości logicznych). (w l » w 2 )— przesunięcie bitowe w prawo — przesuwa lewy operand w prawo o liczbę bitów podaną w operandzie w2 (usuwa ostatnie bity liczby). ( w1 « w2) — przesunięcie bitowe w lewo — przesuwa lewy operand o liczbę bitów podaną w operandzie w2 (uzupełnia zerami postać bitową). Operatory relacji umożliwiają porównanie dwóch wartości. Wynik takiego porównania jest typu b o o l. (w l == w 2 )— zwraca t r u e , jeśli obydwie wartości są równe, (w l != w2) — zwracatrue.jeśliobydwiewartościsąróżne. (w l > w2) — zwraca t r u e , jeśli w l jest większe od w2. (w l >= w2) — zwracatrue,jeśliwljestwiększelubrównew2. Dwa ostatnie operatory można stosować w odwrotny sposób, tj. < i 1) ? 3 : 0. Zmienna x będzie miała wartość 3, jeśli i będzie większe od 1, w przeciwnym razie x będzie równe 0. Operatory posiadają swoje priorytety; niektóre z nich są zgodne z zasadami matematyki (dzielenie jest wykonywane przed dodawaniem itd.). Poznane operatory można uszeregować w następujący sposób według priorytetu operatora:
Przykład: f o r ( i n t l i c z n i k = 0 ; l i c z n i k < 10; l i c z n i k+ + ) I I instrukcje Powyższa pętla wykona się 10 razy. Dodatkowo wewnątrz bloku instrukcji można wykorzystywać wartość zmiennej 1 i c z n i k, np. do wyświetlania jego wartości na ekranie. W pierwszej części pętli inicjujemy zmienną ¡terującą, drugą stanowi warunek; musi on zwracać wartość t rue , aby pętla kontynuowała działanie. W ostatniej części pętli określamy, jak ma się zwiększać (lub zmniejszać) zmienna iteracyjna (w powyższym przykładzie — o jeden). Istnieje możliwość pominięcia dowolnej części pętli; jeśli zachodzi konieczność, aby pętla wykonpala się nieskończoną ilość razy, można użyć zapisu: fo r ( ; ; ) I I instrukcje
Pozostałe dwa rodzaje pętli są używane w sytuacjach, gdy nie jest z góry określone, ile razy pętle mają być wykonywane.
Pola i m eto d y Najważniejszymi elementami klasy są zmienne klasy (nazywane też polami) i metody klasy. Metoda to blok instrukcji mogący przyjąć określone parametry, zwracający określoną wartość. W językach zorientowanych proceduralnie (jak np. C) metody noszą nazwę funkcji. Deklaracja metody składa się z nagłówka oraz ciała: i n t D o d a j ( i n t l i c z b a l , i n t 1 ic z b a 2 )
JA.
i n t w y n ik = l i c z b a l + l i c z b a 2 ; r e t u r n w y n ik ; } Nagłówek metody zawiera typ zwracanej wartości oraz nazwę metody. Następnie znajduje się lista przyjmowanych argumentów. Jeśli metoda nie pobiera argumentów, należy zapisać tylko puste nawiasy; ( ) . Każdy argument składa się z nazwy typu oraz nazwy argumentu. Po nagłówku występuje blok instrukcji, w którym musi wystąpić instrukcja r e t u r n . Powoduje ona zakończenie wykonywania metody (wszelkie instrukcje znajdujące się za nią nie zostaną wykonane) i zwrócenie podanej wartości. Metoda może nie zwracać żadnej wartości; zamiast typu danych jest używane słowo kluczowe v o i d. W tym przypadku użycie słowa kluczowego r e t u rn nie jest wymagane; można go jednak użyć (bez żadnego argumentu), aby przerwać wykonywanie metody: v o id M e t o d a (in t a rg u m e n t)
ii 1= Imwyżej operator znajduje się na powyższej liście, tym większy jest jego priorytet. Aby zmienić priorytet, można zastosować operatory, np. wyrażenie 4+2/2 jest równe 5, a wyrażenie (4 + 2) /2 jest równe 3.
Instrukcje złożone Język C# udostępnia kilka rodzajów instrukcji złożonych. Instrukcja warunkowa pozwala uzależnić wykonanie pewnego ciągu instrukcji od danego warunku, np.: i f ( warunek)
{ } e ls e
gdzie warunek]est tylko i wyłącznie typu b o o l! Przeciwnie niż np. w C + + nie jest możliwe wykonanie następującej operacji: i n t 1i czba = 3; i f ( l i c z b a = 5 ) I I BŁĄD W takiej sytuacji w nawiasie zostaje dokonane przypisanie i wyrażenie przyjmuje wartość 5. W języku C # nie można jednak domyślnie skonwertować tej wartości na typ b o o l, stąd takie wyrażenie spowoduje błąd kompilatora
Instrukcje w pętli są wykonywane dopóty, dopóki iva runek ma wartość t r u e . Należy zwrócić uwagę, że pętla może nie zostać wykonana ani razu! Kolejnym wariantem tej pętli jest pętla d o . . wh i 1 e. Jedyną różnicę między nimi stanowi umiejscowienie warunku — w tym wypadku znajduje się on po bloku instrukcji: do // instrukcje w h ile (warunek)-,
Tablice Do przechowywania wielu elementów tego samego typu używa się zmiennych tablicowych. Tablicę tworzy się z użyciem operatora new, np.: i n t [ ] t a b l i c a = new i n t [ 5 ] ; Powyższa instrukcja utworzy 5-elementową tablicę liczb całkowitych. Aby korzystać z tablicy, należy używać indeksu tablicy ujętego w nawiasy kwadratowe: t a b l i c a [0 ] = 3 ; i n t l i c z b a = t a b l i ca [ 0 ] ; Tablice w języku C# są indeksowane od 0, tj. w tablicy n-elementowej możemy odwoływać się do elementów o indeksach od 0 do n-/ Podobnie jak zwykle zmienne tablice również mogą mieć wartości przypisywane przy ich utworzeniu, np.: i n t [ ] t a b l i c a = new i n t [] { 3 , 5 , 7 ) ; W takiej sytuacji można pominąć rozmiar tablicy; w nawiasach klamrowych wystarczy podać kolejne wartości, jakie mają znaleźć się w tablicy (oddzielone przecinkami). C # podobnie jak inne języki programowania daje możliwość tworzenia tablic wielowymiarowych. W tym celu w momencie deklarowania tablicy należy w nawiasach klamrowych wpisać n-f przecinków, gdzie n jest liczbą określającą, ile wymiarów ma mieć tablica: i n t [ , , ] t a b lic a ; W ten sposób powstanie tablica trójwymiarowa. Podczas tworzenia takiej tablicy musimy podać długości tablicy w poszczególnych wymiarach w sposób następujący: t a b l i c a = new i n t [ 2 , 3 , 4 ] ; Indeks tablicy jest podawany w analogiczny sposób, jak jej wymiary w konstruktorze, np.1 t a b li c a [2 ,2 ,1 ] = 5; Istnieje możliwość przypisania tablicy wielowymiarowej przy utworzeniu, np.: i n t [ , ] t a b l i c a = new i n t [ , ] { { 1 , 3 } , ( 4 , 6 } , { 7 , 9 } , { 1 0 , 12 } } ;
KLASY Klasa jest podstawową formą reprezentowania danych i dostarczania funkcjonalności do programów. Klasy reprezentują różnego rodzaju obiekty, np. komponenty graficzne takie jak przycisk czy pole tekstowe lub złożone mechanizmy obsługi baz danych. Również podstawowe typy danych, opisane powyżej, są klasami. Klasa jest też rodzajem definicji. Konkretny egzemplarz (nazywany też instancją) klasy, o określonej pozycji i opisie tekstowym, np. przycisk znajdujący się w programie, nazywany jest obiektem. Programista może deklarować własne klasy W tym celu należy użyć słowa kluczowego c l a ss: c l a s s C z ło w ie k { } Po słowie kluczowym c l a s s umieszczamy nazwę klasy, a następnie blok instrukcji zawierających deklarację klasy.
Przykład: in t lic z b a ; Nazwa zmiennej może składać się z cyfr, liter i znaku podkreślenia, przy czym nie może zaczynać się od cyfry. Zmiennej przypisuje się wartość za pomocą znaku = (operator przypisania), np.: lic z b a = 5; Zmienne można zadeklarować i przypisać im wartość w jednej instrukcji: in t lic z b a = 5; Za pomocą jednej instrukcji można przypisać dwóm zmiennym jedną wartość, np.: in t l i c z b a , in n a _ ! ic z b a ; lic z b a = in n a _ lic z b a = 3 ; W obrębie metod (więcej na ich temat w dalszych sekcjach) istnieje możliwość deklarowania zmiennych typowanych niejawnie: v a r lic z b a = 3; Trzeba pamiętać, że w przeciwieństwie do języków takich jakJavaScript powyższy zapis deklaruje zmienną silnie typowaną, przy czym ów typ jest określany przez kompilator na podstawie przypisanej wartości. Co za tym idzie, poniższy zapis spowodowałby błąd kompilacji: v a r lic z b a = 3; lic z b a = " t e s t " ;
I I instrukcje
Przykład: s w it c h
Pętla wh i 1 e ma następującą składnię: w h ile ( warunek)
i
( i n t l i c z b a = 2 * a rg u m e n t; re tu rn ; i n t l i c z b a 2 = 2 * l i c z b a ; //ostrzeżenie instrukcja nie zostanie wykonana
}
Parametry metod Zwykłe parametry metod są wymieniane w nawiasach okrągłych po przecinku w sygnaturze (nagłówku) metody. Parametry metod mogą podlegać działaniu różnych modyfikatorów. Dwa pierwsze modyfikatory działają w bardzo podobny sposób. Modyfikatory r e f i o u t pozwalają na przekazywanie parametrów metod przez referencję. Dzięki temu jeśli wewnątrz metody wartość parametru ulegnie zmianie, argument przekazany do metody również zmieni wartość (normalnie do metody przekazywana jest kopia argumentu):
p u b l i c v o id M e to d a (out int waga) { waga = 3 ; 1 p u b l i c v o id In n a M e t o d a (r e f int waga) { waga = 5 ; } p u b l i c v o id T e s t () ( i n t a rg u m e n t, a rgu m e n t2 = 3 ; M e to d a (o u t argument); In n a M e t o d a (r e f argument2); ) Modyfikatory różnią się tym, że zmienna z modyfikatorem o u t nie musi być wcześniej inicjalizowana, a zmienna z modyfikatorem r e f — musi. Co więcej, w przypadku parametru z modyfikatorem o u t istnieje założenie, ze po zakończeniu działania metody przekazany argument będzie miał określoną wartość. W związku z tym wewnątrz metody musi istnieć instrukcja, która przypisze jakąś wartość do parametru z modyfikatorem o u t. Dodatkowo parametry przekazywane przez referencję muszą zawierać modyfikatory r e f i o u t w momencie wywołania metod.
Tablice parametrów Tablice parametrów pozwalają na przekazywanie do metody dowolnej liczby parametrów (po przecinku). Wewnątrz metody są one widoczne w postaci tablicy parametrów; p u b l i c v o id M e to d a P a ra m e try (p a ra m s o b j e c t [ ] o b ie k t y ) ( f o r ( in t i = 0 ; i < o b ie k t y .L e n gth ; 1++) C o n s o le . W r i t e L i n e ( o b i e k t y [ i ] ) ; } Z punktu widzenia metody mamy do czynienia z najzwyklejszą tablicą. Dopuszczalne wywołania metody nie mają jednak z tablicą nic wspólnego: M e to d a P a ra m e try ( " 3 " , " 4 " , 5 ) ; M e to d a P a ra m e try ( " 3 " , " 4 " ) ; M e to d a P a ra m e try ( " 3 " ) ;
Argumenty nazwane i opcjonalne W wywołaniach metod można jawnie podawać nazwy parametrów, dla których chcemy określić wartość, dzięki czemu nie trzeba pamiętać kolejności argumentów: p u b l i c s t a t i c d o u b le P o t ę g a (d o u b le x , d o u b le y ) ( r e t u r n . M a th .P o w (x , y ) ; } C o n s o le . W r it e L i n e (M e to d y . P o t ę g a ( y : 2 , x: 3 )); C o n s o le . Wri t e L i n e (M e to d y . P o tę g a ( x : 2 , y: 3 )); Warto zauważyć, że użycie argumentów nazwanych nie wymaga żadnych ingerencji w deklaracjach metod. Ciąg dalszy na str. 2
Tablice in fo rm a ty c z n e . C # . W yd an ie II Argumenty opcjonalne pozwalaj na pominięcie podawania pewnych argumentów w wywołaniu metody W takiej sytuacji wewnątrz metody są używane ich wartości domyślne: p u b l i c s t a t i c d o u b le O p c j o n a l n e j n t a , d o u b le b = 5 .0 ) ; { re tu rn a * b; } C o n s o le .W r it e L in e ( M e t o d y .O p c jo n a ln e ( 3 , 2 ) ) ; //wyświetla 6 C o n s o le .W ri t e L in e ( M e t o d y . 0 p c j o n a l n e ( 3 ) ) ; // wyświetla 15
Modyfikatory dostępy Metody mają dostęp do zmiennych klasy i do siebie nawzajem. Kwestię dostępu innych klas do metod i pól określonej klasy regulują modyfikatory dostępu. Są one umieszczane przed deklaracją pól i metod: c l a s s C z ło w ie k { p r iv a t e in t w z ro s t; p u b l i c i n t M e to d a () ( // treść metody
} ) Mają one następujące znaczenie: p u b l i c — element jest dostępny dla wszystkich klas. p r i v a t e — element jest dostępny tylko dla metod danej klasy p r o t e c t e d — element jest dostępny dla metod danej klasy i klas po niej dziedziczących (rozdział „Dziedziczenie"). i n t e r n a l — element jest dostępny dla metod danej klasy i wszystkich elementów z tego samego podzespołu (ang assembly). p r o t e c t e d i n t e r n a l — element jest dostępny dla metod danej klasy, klas po niej dziedziczących lub elementów z tego samego podzespołu.
Konstru który Klasa może posiadać specjalną metodę, wywoływaną w chwili utworzenia obiektu. Metoda ta nazywana jest konstruktorem. Konstruktor ma taką samą nazwę jak klasa i me zwraca żadnej wartości: c l a s s C z ło w ie k { p r iv a t e in t w z ro s t; p u b l i c C z l o w i e k j n t p W zro st) I w z r o s t = p W zro st; } } W konstruktorze najczęściej dokonuje się inicjalizacji zmiennych klasy (jak powyżej) i wykonuje się operacje konieczne do prawidłowego jej działania. Konstruktory z reguły są oznaczone słowem p u b lic , gdyż to właśnie za ich pomocą najczęściej są tworzone obiekty. Klasa może posiadać wiele konstruktorów, w tym konstruktor domyślny (niepobierający żadnych argumentów).
Destruktory Konstruktor jest wywoływany przy tworzeniu obiektu, natomiast destruktor przy jego mszczeniu. Składnia destruktora jest następująca:
-nazwaKl asy() ( ) Destruktor me może przyjmować żadnych argumentów ani zwracać wartości. Nie może być też wywoływany przez programistę (obiekty są zwalniane automatycznie przy użyciu składnika CLR o nazwie garbage collector). Klasa może zawierać tylko jeden destruktor; nie może on też być dziedziczony
Inicjacja pól Istnieje możliwość nadania zmiennym klasy wartości już w trakcie jej deklarowania.
Dziedziczenie Niektóre klasy mają wiele wspólnych cech. Wszystkie kontrolki graficzne mają ustalony rozmiar, kolor czy punkt położenia. Wiąże się to z posiadaniem przez nie pewnych wspólnych metod I pól. Zamiast deklarować te same metody i pola w każdej z klas, projektanci platformy NET wykorzystali mechanizm dziedziczenia i utworzyli |edną wspólną klasę dla kontrolek: C o n t r o l Wszystkie kontrolki dziedziczą po mej, dzięki czemu uzyskują dostęp do je| metod, pól i Innych elementów posiadających modyfikatory dostępu p ubl i c, p r o t e c t e d oraz p r o t e c t e d i n t e r n a l (jak również i n t e r n a l , chociaż nie jest to regułą) Jeśli klasa B dziedziczy po klasie A, a jakaś metoda przyjmuje jako argument obiekt klasy A, można również podać obiekt klasy B: c la s s A { } c la s s B : A { } p u b l i c v o id m e to d a (A o b i e k t ) { } B o b ie k t B = new B ( ) ; m etoda ( o b i e k t B ) ; Aby zadeklarować klasę dziedziczącą po innej, stosuje się następującą konstrukcję: c la s s Ssak : {
Przykład: c l a s s C z ło w ie k { p u b l i c s t a t i c f l o a t o b lic z B M I ( i n t w a ga , f l o a t w z r o s t ) { //treść
} } // inne instrukcje f l o a t BMI = C z ło w ie k . o b i i c z B M I( 7 5 , 2 . O F ) ;
} W tej sytuacji w klasie pochodnej musi zostać zadeklarowana metoda r u s z a j(): c l a s s C z ło w ie k : S s a k { p u b l i c o v e r r i d e v o id r u s z a j ( i n t k ie r u n e k ) (
} ) Nagłówki metod są identyczne; zamiast słowa a b s t r a c t pojawiło się słowo o v e r r i de. Oznacza ono, że dana metoda przesłania metodę z klasy nadrzędnej. Istnieje możliwość przesłonięcia metody nawet wtedy, gdy metoda została zadeklarowana w klasie nadrzędnej.
Przyldad: c la s s Ssak { p u b l i c v i r t u a l v o id r u s z a j ( i n t k ie r u n e k ) { // treść metody } ) c l a s s C z ło w ie k : S s a k ł p u b l i c o v e r r i d e v o id r u s z a j ( i n t k ie r u n e k ) }
{ p u b l i c s t a t i c v o id S t a t y c z n a M e to d a Q { } p u b lic s t a t ic j
{ } v o id S p a n i e . s p i j ( ) ł ) ) Implementowanie Interfejsu określa się również za pomocą znaku dwukropka. Jeśli klasa dziedziczy po innej klasie, a jednocześnie implementuje jeden lub więcej interfejsów, jako pierwszą po dwukropku należy podać nazwę klasy, a następnie po przecinkach nazwy interfejsów: c l a s s C z ło w ie k : S s a k , S p a n ie Metody interfejsu nie posiadają modyfikatorów dostępu; łatwo odróżnić je od metod klasy dzięki temu, że nazwa implementowanej metody musi być poprzedzona nazwą interfejsu (np. v o id S p a n ie .s p ijO ) .
Struktury // błąd
kompilatora
!
{ }
Przykład blokowania przesłaniania metody (dotyczy tylko metod, które są oznaczone słowem o v e r r i de): c la s s Ssak { p u b l i c v i r t u a l v o id r u s z a j ( i n t k ie r u n e k ) { } : Ssak
{ p u b l i c s e a le d o v e r r i d e v o id r u s z a j ( i n t k ie r u n e k ) { } } c l a s s S u p e r C z lo w ie k
Chociaż C # nie obsługuje wielokrotnego dziedziczenia, podobną funkcjonalność zapewniają interfejsy. Deklaracja interfejsu zawiera deklaracje nagłówków metod oraz innych złożonych elementów, omówionych w dalszych podrozdziałach (delegacji, zdarzeń i właściwości). Interfejs nie zawiera jednak treści metod — mają je zapewnić klasy, które dany Interfejs będą implementować. Interfejs deklaruje się przy użyciu słowa kluczowego i n t e r f ace: i n t e r f a c e S p a n ie { v o id s p i j ( ) ; 1 c l a s s C z ło w ie k : S p a n ie p u b l i c v o id r u s z a j ( i n t k ie r u n e k )
Przykład blokowania dziedziczenia:
: C z ło w ie k
{ p u b l i c o v e r r i d e v o id r u s z a j ( i n t k ie r u n e k ) ( } // błąd kompilatora!
}
Struktura to konstrukcja bardzo podobna do klasy, Stosuje się ją głównie do przechowywania obiektów wymagających niewielkiej Ilości danych i prostej funkcjonalności. Strukturami są np. struktura S y s t e m . D raw i n g . P oi n t — przechowuje dane punktu o określonych współrzędnych; struktura S y ste m . D raw i n g . C o lo r — przechowuje informaqe o kolorze. Strukturę deklaruje się przy użyciu słowa kluczowego s t r u c t : s tru c t S tru k tu ra f } Najważniejsze różnice między strukturą a klasą to: • Brak możliwości dziedziczenia struktur Struktury nie mogą być odziedziczone ani dziedziczyć po innych strukturach lub klasach. • Sposób przechowywania struktur w pamięci. Struktury są przechowywane jako wartości, a nie (jak obiekty klas) jako referencje. • Brak możliwości Inicjacji pól. Zmienne struktury nie mogą być inicjowane tak, jak zmienne klasy. • Brak destruktorów.
Instrukcja foreach
Za pomocą Instrukcji f o r e a c h możliwe jest wykonanie operacji na wszystkich elementach danej kolekcji obiektów lub tablicy.
Jeśli do atrybutów klasy zostanie dodane słowo kluczowe p a r t i a l , jej deklaracja będzie mogła zna|dować się w kilku plikach. Warto pamiętać, że każda klasa, nawet jeśli jawnie nie dziedziczy po jakiejś klasie, jest pochodną klasy Obj e c t . Jest to klasa bazowa dla wszystkich klas; dzięki temu często wykorzystuje się ją jako parametr w różnego rodzaju metodach.
Przykład: i n t [ ] l i c z b y = new i n t [] ( 0 , 1 , 2 , 3 , 4} fo re a c h ( in t i in lic z b y ) { // wykonaj operacje przy użyciu zmiennej i
)
Tworzenie obiektów Każdy obiekt po zadeklarowaniu go, a przed jego utworzeniem ma wartość n u 11. Jest to wartość specjalna; oznacza ona, ze obiekt nie został utworzony. Obiekty, czyli egzemplarze danej klasy, są najczęściej tworzone przy użyciu konstruktora i słowa kluczowego new, np.: c l a s s C z ło w ie k ł p u b l i c C z l o w i e k ( S t r i n g p N a zw isk o ) { n a z w is k o = p N a z w is k o ;
1
i n t S t a t y c z n e P o le = 3 ;
}
{
Jak widać, nleabstrakcyjną metodę, która może być przesłaniana przez klasy pochodne, należy oznaczyć słowem kluczowym v i r t u a l . Istnieje możliwość zablokowania dziedziczenia klasy lub przesłaniania metody w klasach pochodnych. Śluzy do tego celu słowo kluczowe s e a le d .
i c l a s s C z ło w ie k
jednym z najpopularniejszych przykładów użycia metod statycznych jest klasa S y s t e m .Math. Udostępnia ona szereg statycznych metod służących do obliczania m.in. funkcji trygonometrycznych: d o u b le s in u s = M a t h . S i n ( 4 5 . 0 ) ; Również pola mogą być deklarowane jako statyczne. Jeśli klasa zawiera tylko pola i metody statyczne, może zostać oznaczona jako klasa statyczna: s t a t ic c la s s S ta ty c z n a
Interfejsy
// treść metody
s e a le d c l a s s S s a k { } c l a s s C z ło w ie k : S s a k
} p r i v a t e S t r i n g n a z w is k o ; } // inne instrukcje
C z ło w ie k p ie r w s z y = new C z lo w i e k ( „ K o w a l s k i " ) ; Inną metodą, rzadziej wykorzystywaną, jest tworzenie obiektów przy użyciu metod statycznych.
p u b l i c i n t Waga { get { r e t u r n w aga;
Metody statyczne mogą być wywoływane bezpośrednio przy użyciu klasy, a nie obiektów.
{ } Oznacza to, ze nie jest możliwe utworzenie obiektu danej klasy Dopiero obiekty klas pochodnych mogą być tworzone (o ile te klasy nie zostaną oznaczone jako abstrakcyjne). Klasa staje się abstrakcyjną również wtedy, gdy któraś z jej metod zostanie oznaczona jako abstrakcyjna: a b s tr a c t c la s s Ssak { p u b l i c a b s t r a c t v o id r u s z a j ( i n t k ie r u n e k ) ;
Przykład: c l a s s C z ło w ie k { p r i v a t e i n t w z r o s t = 1 75 ; // dalszy ciąg klasy }
Metody statyczne
// treść klasy 1 c l a s s C z ło w ie k : S s a k { // treść klasy ) C # nie oferuje wielokrotnego dziedziczenia (znanego np. z C + +), czyli dziedziczenia po wielu klasach jednocześnie. Niektóre klasy (np. S tre a m ) są oznaczone jako abstrakcyjne; a b s tra c t c la s s Ssak
Zmienna iteracyjna musi mieć taki sam typ jak element tablicy lub kolekcji obiektów W przypadku obiektów wymagania Instrukcji f o r e a c h są bardziej zlozone. Obiekt dane| klasy bądź struktury musi udostępniać elementy G et Enu m e ra t o r, M oveNext, R e s e t i C u r r e n t , które są oferowane przez Interfejsy IE n u m e ra b le o ra z I En u m e ra to r. Każda klasa lub struktura, która implementuje te dwa Interfejsy, może być wykorzystana w instrukcji f o r e a c h .
Właściwości
Chociaż zmienne klasy są zazwyczaj deklarowane jako prywatne, programiści często udostępniają je pośrednio przy użyciu właściwości, Właściwość jest konstrukcją, za pomoq której można uzyskać dostęp do określonej cechy danej klasy. Najprostszym zastosowaniem właściwości jest „opakowanie" zmiennej klasy: c l a s s C z ło w ie k f p r i v a t e i n t w aga;
2
} set { waga * v a lu e ; } } ł W sekcji g e t jest zwracana wartość; nie musi ona składać się jedynie z instrukcji r e t u r n ; można także dołączyć instrukcje sprawdzające np. poprawność przechowywanych danych. Podobna sytuacja występuje w bloku s e t . Pojawia się w nim słowo kluczowe v a lu e . Przechowuje ono wartość, która została nadana właściwości przez programistę. Gdybyśmy chcieli dodać warunek, który pozwoli na ustawienie jedynie wagi o wartości większej od zera, należałoby skorzystać z następującej konstrukcji: set ( i f ( v a lu e > 0 ) waga = v a lu e ; ) Właściwości są również często używane przy projektowaniu interfejsu aplikacji (design-time), kiedy to dzięki nim można udostępnić niektóre pola klasy do edycji.
Właściwości implementowane automatycznie Począwszy od C # 3.0, istnieje możliwość stosowania skróconych deklaracji właściwości. Są one stosowane w sytuacjach, gdy właściwość stanowi jedynie opakowanie dla prywatnego pola klasy, przez co konstrukcjaakcesorów g e t i s e t jest trywialna. Można uniknąć tworzenia nadmiarowego kodu, stosując właściwości implementowane automatycznie: c l a s s C z ło w ie k { p u b l i c i n t Waga { g e t ; s e t ; } 1 W przypadku tej właściwości nie trzeba jawnie deklarować prywatnego pola klasy, w którym wartość będzie przechowywana Nie trzeba także podawać elementarnych bloków g e t (z instrukcją return) i s e t (z przypisaniem wartości v a l ue) Taka właściwość może być traktowana tak jak wszystkie Inne. Jeśli chcesz utworzyć właściwość tylko do odczytu lub tylko do zapisu (tj. jeden z akcesorów ma być publiczny, a drugi prywatny), mozesz skorzystać ze słowa kluczowego p r iv a t e : c l a s s C z ło w ie k i p u b l i c i n t Waga { g e t ; p r i v a t e s e t ; } }
Indeksery
Niektóre obiekty, np. listy, istotę swo|ego działania opierają na dostępie do tablicy (bądź innej struktury danych) zawierającej elementy listy. Aby ułatwić dostęp do takiej kluczowej zmienne], można wykorzystać indekser. Dzięki niemu można odwołać się do danego elementu klasy przy użyciu nawiasów kwadratowych, zastosowanych bezpośrednio do nazwy obiektu: L i s t a L i c z b l i s t a = new L i s t a L i c z b ( ) ; l i s t a [0 ] = 3 ; Aby klasa mogła korzystać z indeksera, oprócz stosownej zmiennej przechowującej dane należy zastosować konstrukcję indeksera, jak na poniższym przykładzie: c la s s L is t a L ic z b { p r i v a t e i n t [] l i c z b y = new i n t [ 1 0 ] ; p u b l i c i n t t h i s [ i n t in d e x ] { get í re tu rn 1ic z b y [ in d e x ] ; } se t f l i c z b y [ i n d e x ] = v a lu e ; } } } // inne instrukcje L i s t a L i c z b l i c z b y = new L i s t a L i c z b ( ) ; lic z b y [ 0 ] = 3; i n t zm ie n n a = l i c z b y [ 0 ] ; Kompilator Interpretuje słowo t h i s jako oznaczenie Indeksera. Typ i n t przed słowem t h i s określa rodzaj zwracanego elementu, natomiast określenie i n t i ndex definiuje typ indeksu, według którego będzie uzyskiwany dostęp do obiektu. Sama czynność uzyskiwania i zapisywania danych odbywa się jak w zwyczajnej właściwości. Oczywiście powyższa klasa powinna zostać zaopatrzona w stosowne zabezpieczenia, np. uniemożliwiające odwołanie spoza zakresu tablicy itp.
Delegacje We wszystkich powyższych przykładach parametrami metod mogły być tylko zmienne przechowujące dane. C#, podobnie jak większość języków programowania, umożliwia też wykorzystanie w ten sposób metod, jest to jedno z najpopularniejszych zastosowań mechanizmu delegacji. Delegację deklaruje się podobnie jak metodę, dodając słowo kluczowe d e l eg a te: p u b l i c d e le g a t e v o id Wyswi e tlK o m u n i k a t ( S t r i ng v a l u e ) ; Od tego momentu można tworzyć obiekty delegacji, które odwołują się do konkretnych metod. Metody te muszą mleć identyczny nagłówek jak delegacja, np. p u b l i c v o id W y s w ie t lW O k ie n k u (S t r in g w a rto ść) { M e s s a g e B o x .S h o w (w a r t o s c ); }
Tablice in fo rm a ty c z n e . C # . W yd an ie II Dysponując taką metodą, można utworzyć obiekt delegacji i korzystać z niego (nazwę metody należy podać jako parametr konstruktora delegacji, niezależnie od parametrów w niej zadeklarowanych): W y św ie tl K o m u n ik a t d e l e g a c j a = new Wyswi e tlK o m u n i k a t(W y ś w ie tlW O k i e n k u ) ; d e le g a c ja (" t r e s c " ); Jak juz wspomniałem, z typu delegacp można korzystać jak z każdego innego typu, również wykorzystując go jako parametry dla metod: p u b l i c v o id In n a M e to d a (W y sw ie tlK o m u n i k a t m etoda) { M e t o d a ( " je s z c z e in n y k o m u n ik a t " ); } Delegacje są bardzo często wykorzystywane w mechanizmie zdarzeń.
Zdarzenia Mechanizm zdarzeń umożliwia reakcję programu na różne sytuacje, takie jak kliknięcie przycisku, zaznaczenie opcji czy wczytanie danych. Dzięki temu mechanizmowi w momencie zajścia takiego zdarzenia informowane są wszystkie obiekty, które uprzednio zadeklarowały chęć nasłuchiwania zdarzeń. Aby dodać do danego zdarzenia metodę obsługi, wykorzystuje się operator +=: p u b l i c v o id M e t o d a O b s lu g i( o b j e c t s e n d e r , E v e n t A r g s e) (
re tu rn }
"Ssak,
Oto przykład:
";
} c l a s s C z ło w ie k : S s a k { p u b l i c C z l o w i e k ( S t r i n g im ię ) : b a se () { M e ssa g e B o x . S h o w ("tw o rzym y o b ie k t c z lo w ie k a " ) ; t h i s . im ię = im ię ; } p u b lic bool Porów naj L u d z i( C z ło w ie k c) ( re tu rn ( c .T o S t r in g O T o Stri n g( ) ) ;
- = t h is .
} p u b lic o v e r rid e S t r in g T o S t r in g O { re tu rn b a s e .T o S t r in g O + " C z ło w ie k - 11 + t h i s . im ię ; } p u b l i c b o o l T e s to w a ( ) f re tu rn t h is .P o r o w n a jL u d z i( t h i s ) ; //zawsze zwróci true
i p r iv a t e S t r in g
im ię ;
// treść obsługi } S y s t e m .W in d o w s .F o r m s .B u tt o n p r z y c i s k = new S y s t e m .W in d o w s .F o r m s . B u t t o n ( ) ; p r z y c i s k . C l i c k += new S y ste m . E v e n t H a n d le r (M e t o d a O b s lu g i) ; Zdarzenie C l i c k przycisku przyjmuje domyślny typ zdarzeń, czyli E v e n tH a n d l e r. Jest to delegacja, której nagłówek jest taki, jak nagłówek M etod aO b sl u g i () Operator += oznacza, ze do danego zdarzenia może być przypisanych wiele obiektów delegacji — wszystkie one będą informowane o danym zdarzeniu. Aby móc dodać dowolną metodę obsługi zdarzenia, trzeba znać nazwę zdarzenia obiektu (np. C l i c k ) , nazwę delegacji (np. E v e n tH a n d l e r) i jej budowę oraz nazwę metody wywołanej przez zdarzenie (M etodaO bsl u g i).
Rzutowanie Jedną z najczęściej wykonywanych czynności jest konwersja między typami danych. Najłatwiej jest dokonać konwersji typów prymitywnych (np. liczbowych) na typ S t r i n g — wystarczy wywołać metodę T o S t r i n g O zadeklarowanąwklasieobject.acozatymidzie — dostępną we wszystkich klasach języka C# Czasem zachodzi konieczność skonwertowania np. typu zmiennoprzecinkowego na typ całkowitoliczbowy. W takiej sytuacji można wykorzystać operację rzutowania: i n t zm ie n n a = ( i n t ) 4 . 5 ; Nie zawsze jednak można tego dokonać. Instrukcji rzutowania należy używać z rozwagą, głównie dla typów prymitywnych oraz zdefiniowanych przez programistę. Do konwersji obiektów klas, struktur i interfejsów zalecane jest użycie operatorów a s i i s. Operator i s przyjmuje dwa argumenty — po lewej stronie obiekt, po prawe| nazwę klasy, np.: S y s t e m .W in d o w s .F o r m s .B u tt o n p r z y c i s k = new S y s t e m .W in d o w s .F o r m s .B u t t o n ( ) ; i f ( p r z y c i s k i s C o n t r o l) { // blok instrukcji wykona się
} Wyrażenie z użyciem operatora i s zwróci tru e , jeśli obiekt nie ma wartości n u l i i jest możliwa konwersja danego obiektu na obiekt danej klasy bez wygenerowania wyjątku. Operator a s przeprowadza rzutowanie lewego argumentu na obiekt klasy określonej prawym argumentem i zwraca ten obiekt lub wartość n u 11, jeśli operacja nie jest możliwa. S y ste m .W in d o w s. F o rm s. C o n t r o l p r z y c i s k = new S y s t e m .W in d o w s .F o r m s .B u t t o n ( ) ; S y s t e m .W in d o w s .F o r m s .B u tt o n nowy = p r z y c i s k a s S y s t e m .W in d o w s .F o rm s. B u tto n ;
Typ wyliczeniowy Zmienna typu wyliczeniowego zawiera zbiór stałych określonych nazwami i wartościami, Typ wyliczeniowy jest deklarowany z użyciem słowa kluczowego enum (wewnątrz klasy, ale nie w metodzie!): enum M ie s ią c e { S t y , L u t , M a r , K w i , M a j , C z e ,L ip ,S ie ,W r z ,P a z ,L is ,G r u ) M ie s ią c e m ie ś = M i e s i ą c e . S t y ; Dodatkowo można dokonać konwersji typu wyliczeniowego na całkowitoliczbowy. Domyślnie pierwszy element zbioru ma wartość 0, a każdy koleiny jest o 1 większy od poprzednika. W momencie deklaracji można nadać kolejnym elementom zbioru wartości, np.: enum M ie s ią c e { S t y = 5 ,L u t ,M a r ,K w i,M a j, C z e ,L ip ,S ie ,W r z ,P a z ,L is ,G r u ) W ten sposób elementy zbioru będą miały wartości od 5 do 16.
Słowa kluczowe this i base Słowo kluczowe t h i s jest używane w obrębie danej klasy, jeśli istnieje konieczność odniesienia się do jej własnych metod, pól i innych elementów. Użycie słowa t h i s, np. jako parametru dla metody, powodu|e przekazanie całego obiektu tej klasy. Słowo kluczowe b a se pozwala na odwołanie się w klasie potomnej do metod i właściwości klasy bazowej.
Przykład użycia obydwu słów kluczowych: a b s tr a c t c la s s Ssak { p u b lic S s a k ( ) { M e s s a g e B o x .S h o w (" T w o r z e n ie o b ie k t u s s a k a " ) ; ) p u b lic o v e r rid e s t r in g T o S t r in g O
S t r in g ś c ie ż k a = " c t W s c ie z k a " ; C # akceptuje też zapisywanie łańcuchów w postaci literałów @. Literały takie zapisuje się, zaczynając łańcuchy od znaku @, np.: S t r i n g in n y _ t e k s t = @ " ja k is t e k s t " ; Łańcuchy @nie są przetwarzane przez program, można więc zapisywać w nich znaki lewego ukośnika bez użycia podwójnego lewego ukośnika: S t r i n g in n a S c i e z k a = @ " c : \ s c ie z k a \ p li k . t x t " ; Aby u ż y ć w t a k im ła ń c u c h u z n a k c u d z y s ło w u , n a le ż y z a p i s a ć go dwa ra zy : S tr in g te k s t = " " k o le jn y t e k s t " " - t e k s t w c u d z y s ł o w ie " ; // wyświetla: „ Kolejny tekst" - tekst w cudzysłowie
Klasa S s a k przesłania metodę T o S t r i n g ( ) , która jest używana przez wszystkie klasy do zwrócenia najważniejszych wartości i opisów (jest zadeklarowana w klasie Obj e c t). W klasie C z l owi ek w kilku metodach odwołujemy się do obiektu samej klasy (choć nie jest to wymagane). Wreszcie w metodzie T e sto w a () korzystamy ze słowa t h i s, aby przekazać aktualny obiekt. Jako żewmetodzie P o ró w n a j L u d z i ( ) obiekt podany w parametrze jest porównywany z aktualną referencją obiektu (ponownie słowo kluczowe t h i s), metoda T e sto w a ( ) zawsze zwraca t r u e . Słowo kluczowe b a s e pojawia się w dwóch miejscach: w m e tod zieTo String()klasyCzlow iek(d ziękitem u wynik działania tej metody przyjmuje postać „Ssak, Człowiek — imię") oraz w konstruktorze (w tym przypadku stanowi odwołanie do konstruktora klasy bazowe|). Musi ono być umieszczone przed właściwym blokiem instrukcji.
Atrybuty
} Atrybuty, będące w istocie normalnymi klasami, mogą przyjmować różnego rodzaju parametry, Dobry przykład stanowi atrybut A t t r i b u t e lls a g e , stosowany w deklaracjach klas atrybutów: [ A t t r i b u t e lls a g e ( A t t r i b u t e T a r g e t s . C la s s , A llo w M u lt ip le = f a ls e ) ] c l a s s W a z n o s c K la s y : A t t r i b u t e (
C # oferuje obsługę wyjątków przy użyciu klauzuli t r y . . c a t c h . . f i n a l l y . Czynności, które mogą spowodować powstanie wyjątku (np. przerwanie połączenia sieciowego, błąd zapisu danych na dysku itp.) są ujmowane w blok instrukcji oznaczony słowem kluczowym t r y . Następnie jest umieszczany blok c a t c h , w którym umieszcza się czynności informujące użytkownika o błędzie (w zależności od rodzaju błędu, który jest identyfikowany na podstawie klasy wyjątku). Wreszcie w sekcji f i na 11 y, bez względu na to, czy wystąpił wyiątek, czy nie, zwalniane są wykonywane instrukcje konieczne do poprawnego działania programu (np zamykanie otwartych strumieni).
Przykład; F ile S t r e a m try
s t r = n u li;
p u b l i c i n t W a rto ść { g e t ;
c a t c h ( F ile N o t F o u n d E x c e p t io n e x ) { M e s s a g e B o x .S h o w (" B ra k p l i k u ; " + e x . F i le N a m e ); } f in a lly I i f ( s t r != n u l l ) s t r .C lo s e ();
Klasa Array
Każda tablica jest także obiektem. Jednocześnie wszystkie tablice dziedziczą po klasie A r r a y . Dzięki temu można wywoływać szereg metod i właściwości udostępnianych przez tę klasę. Oprócz tego klasa A r r a y upubliczma metody statyczne, zapewniające dodatkową funkcjonalność. Poniżej znajduje się opis niektórych z nich:
Metody klasy Array (statyczne) v o id C o p y (A r r a y z r o d l o , A r r a y c e l , i n t i 1 o s c ) — kopiuje i lo s e elementów od początku tablicy z r o d l o do tablicy c e l (wklejanie odbywa się również od początku), v o id R e v e r s e ( A r r a y t a b l i c a ) — odwraca kolejność elementów tablicy. v o id S o r t ( A r r a y t a b l i c a ) — sortuje tablicę (elementy tablicy muszą być typu, który implementuje interfejs ¡C o m p a ra b le ).
Klasa String Do przechowywania łańcuchów znaków służy w języku C# klasa S t r i ng. Jest ona klasą dość wyjątkową, aby utworzyć nowy łańcuch znaków, nie trzeba korzystać z konstruktora — wystarczy po prostu przypisać wartość zmiennej: S t r i n g ła ń c u c h = " t e k s t " ; Tekst musi być ujęty w cudzysłowy. Jeśli istnieje konieczność zawarcia w tekście znaku cudzysłowu bądź innych znaków specjalnych (znaki końca wiersza, nowej linii, tabulacji), używa się do tego celu znaku \ (lewy ukośnik) w połączeniu z innym znakiem. Do zapisania lewego ukośnika w łańcuchu wykorzystuje się podwójny lewy ukośnik (\\).
}
i u b l i c i n t Waga { g e t ; p r i v a t e s e t ; ) }
Funkcje anonimowe Funkcje anonimowe w C # występują pod dwiema postaciami: metod anonimowych i wyrażeń lambda. Funkcje anonimowe pozwalają na wygodne i zwięzłe deklaracje funkcji, z możliwością jednoczesnego wykorzystania ich w kodzie (nie trzeba rozróżniać deklaracji od użycia — stąd nazwa wyrażenia). Wyrażenia lambda są znacznie krótsze, niemniej można z nich korzystać, począwszy od NET 3.5 (C# 3.0), podczas gdy z metod anonimowych można korzystać również w NET 2.0 (C# 2.0).
); t.S ta rt(" te s t" ); Kompilator sam rozróżnia podane metody anonimowe; jest on w stanie dopasować zarówno metodę bezparametryczną (do delegacji typu T h r e a d S t a r t ), jak i parametryczną (do delegacji typu P a r a m e tr i z e d T h r e a d S t a r t ). Wyrażenia lambda stanowią usprawnienie metod anonimowych, głównie pod względem zwięzłości i przejrzystości zapisu Odnosząc się do poprzedniego przykładu, efekt przepisania go w wersji bezparametrycznej przy użyciu wyrażeń lambda jest następujący: T h re a d t = new T h r e a d ( () => C o n s o le .W r ite L in e (" N o w y w ą te k") ); t.S ta r t(); Tak naprawdę powyższy przypadek wyrażenia lambda jest niezwykle specyficzny. Głównym zastosowaniem tego typu wyrażeń jest wykonywanie operacji na podanych argumentach, co najczęściej wiąże się ze zwracaniem wartości. W wyrażeniach lambda nie trzeba jednak korzystać z instrukcji r e t u r n : d e le g a t e d o u b le F u n k c ja Je d n o w y m ia ro w a (d o u b le x ) ; s t a t i c v o id M a i n ( s t r i n g [ ] a r g s ) F u n k c ja Je d n o w y m ia ro w a o d w ro tn o ść = ( x ) => (x != 0 ? l / x : D o u b le . P o s it iv e ln f in it y ) ; C o n s o le . W r it e L in e ( o d w r o t n o ś ć ( 3 ) ) ; C o n s o le .R e a d K e y O ; W tym przypadku najpierw deklarujemy delegację typową dla jednowymiarowych (|ednoargumentowych) operacji arytmetycznych. Do tego typu delegacji przypisujemy jednoargumentowe wyrażenie lambda, którego treścią jest proste wyrażenie arytmetyczne — jeśli x jest różne od 0, możemy obliczyć odwrotność podanej liczby, w przeciwnym razie zwracamy +oo. Następnie możemy używać delegacji w klasyczny sposob — tak jakby była ona funkcją. W powyższym przykładzie nie podaliśmy typów argumentów w wyrażeniu lambda, choć jest to oczywiście dopuszczalne: F u n k c ja Je d n o w y m ia ro w a o d w ro tn o ść = (d o u b le x ) => (x != 0 ? l / x : D o u b le . P o s it iv e ln f in it y ) ; Wyrażenia lambda są często wykorzystywane w połączeniu z językiem LINQ i API kolekcji (przestrzeń nazw S y s t e m . Co l 1 e c t i o n s . G e n e r i c), dlatego więcej przykładów znajduje się w sekcji poświęconej tym zagadnieniom.
Metody rozszerzające Metody rozszerzające pozwalają na dodawanie (rozszerzanie) funkcjonalności już istniejących klas bez konieczności ingerencji w ich deklaracje tudzież tworzenie klas dziedziczących. Bardzo dobry przykład stanowi klasa S t r i ng — jest to klasa zamknięta (s e a l ed), dlatego tez nie można utworzyć klasy pochodnej, a jednocześnie klasie S t r i n g brakuje kilku przydatnych operacji, z których jedną jest możliwość odwrócenia łańcucha. Nic nie stoi na przeszkodzie, aby utworzyć metodę rozszerzającą: c l a s s P ro gra m { s t a t ic
v o id M a i n ( s t r i n g [ ]
a rgs)
C o n s o le . W r i t e L i n e ( " a b e d " . R e v e rs e ()); C o n s o le .R e a d K e y O ;
Metody anonimowe Metoda anonimowa pozwala na stworzenie wewnętrznej deklaracji metody, bez konieczności podawania jej nazwy, w miejscu, w którym normalnie należałoby podać wartość typu delegacyjnego. Rozważmy przykład kodu tworzącego najprostszy wątek: s t a t i c v o id M a i n ( s t r i n g [ ] a r g s ) T h re a d z w y k ły = new T h re a d (n e w T h re a d S ta rt(M e to d a )); z w y k ły .S t a r t ( ) ;
Metody klasy Array i n t G e t L e n g t h ( ) — zwraca liczbę elementów tablicy, v o id C o p y T o ( A r r a y t a b l i c a , i n t in d e x ) — kopiuje całą zawartość swojej tablicy do zmiennej ta b l i ca; pierwszy wypełniony element zmiennej t a b l i ca będzie miał indeks i ndex.
se t;
} W tym przypadku pierwszy argument stanowi wartość typu wyliczeniowego A t t r ib u t e T a r g e t s .J e s t t o wartość, którą normalnie przekazuje się w konstruktorze klasy A t t r i b u te U sa g e . Wartość C l a s s oznacza, ze atrybut można stosować tylko do klas. Następnie po określeniu tego jednego, wymaganego parametru możemy przekazywać parametry nazwane, dzięki którym można określić wartość właściwości tego atrybutu. W tym przypadku określamy właściwość A 1 1 owMu 11 i p 1 e, zabraniając używania tego atrybutu do innych klas wielokrotnie. Aby zastosować nowy atrybut wobec starej klasy, należy zastosować następujący zapis: [ S e r ia liz a b le ] [ W a g a K la s y (W a r to s c = 5 )] c l a s s C z ło w ie k
s t r = F ile .0 p e n R e a d (@ " c :\ n ie is t n ie ja c y P lik .t x t " );
Oto p r z y ld a d : T h re a d t = new T h r e a d ( d e l e g a t e ( o b j e c t o) { C o n s o le . W r ite L in e ( " N o w y w ą te k : " + o ) ; }
Wyrażenia lambda
Atrybuty pozwalają na dodawanie do klas, interfejsów, metod i innych elementów języka C # specjalnych informacji, stanowiących swego rodzaju metadane. Atrybuty me wpływają bezpośrednio na kod klasy, ale za to na jej działanie. Atrybuty są intensywnie wykorzystywane m.in. w WCF, gdzie niewielkie zmiany wprowadzane w wartościach atrybutów potrafią modyfikować działanie całych aplikacji! Od strony praktycznej atrybut jest klasą, która dziedziczy po klasie S y s t e m . A t t r i b u tę . Zgodnie z konwencją klasa atrybutu powinna kończyć się słowem A t t r i b u tę . Wykorzystując atrybut, należy podać jego nazwę w nawiasach kwadratowych przed wybranym elementem. Jednym z najbardziej znanych atrybutów jest S e r i a l i z a b l e. Klasa oznaczona takim atrybutem może być serializowana, np. za pomocą klasy B i n a r y F o r m a t te r lub S o a p F o r m a tte r : [ S e r i a l i ż a b ie ] c l a s s C z ło w ie k { p u b lic i n t Waga { g e t ; p r iv a t e s e t ; }
Wyjątki
Oczywiście do metod anonimowych można przekazywać argumenty. Kontynuując przykład, klasa T h re a d przyjmuje także delegację typu P a ra m e tr i z e d T h r e a d S t a r t o następującej treści: d e l e g a te v o id P a r a m e t r iz e d T h r e a d S t a r t (O b je c t o b i e k t ) ;.
s t a t i c v o id M e to d a () ( C o n s o l e .W r ite L in e ( " N o w y w ą t e k " ) ; } Klasa T h re a d wymaga przekazania parametru będącego delegacją typu T h r e a d S t a r t — jest to delegacja bezparametryczna, niezwracająca żadnej wartości. W związku z tym konieczne było utworzenie tradycyjnej deklaracji metody, nawet jeśli nie pojawi się ona w żadnym innym miejscu kodu. Konstrukcję tę można uprościć, stosując metodę anonimową: s t a t i c v o id M a i n ( s t r i n g [ ] a r g s ) { T h r e a d t = new T h r e a d ( d e l e g a t e ( ) { C o n s o le .W r it e L in e ( „ N o w y w ą t e k " ) ; } ); t.S ta rt(); } W tym momencie zamiast instrukcji tworzącej nowy obiekt delegacji typu T h r e a d S t a r t tworzymy deklarację metody anonimowej. Rozpoczyna się ona od słowa kluczowego d e le g a t e , po którym następuje wykaz parametrów metody (w tym przypadku brak), a następnie jej treść. Nie określa się typu zwracanej wartości — jeśli metoda ma zwrócić wartość, należy po prostu zastosować instrukcję r e t u r n w treści metody.
3
s t a t i c c l a s s M etody { p u b lic s t a t i c S t r in g R e v e r s e (t h is S t r i n g ła ń c u c h ) i c h a r [ ] z n a k i = 1 a n c u c h .T o C h a r A r r a y O ; i n t o s t a t n i = z n a k i . L e n g t h - 1; f o r ( in t i = 0 ; i < z n a k i.L e n g t h
/ 2 ; 1++) { c h a r ch = z n a k i [ o s t a t n i - i ] ; znaki [o s ta tn i - i] = znaki [ i ] ; z n a k i[ i] = ch; } r e t u r n new s t r i n g ( z n a k i ) ; } } Warto zauważyć, że deklaracja metody rozszerzającej musi spełnić dwa warunki: po pierwsze, metoda musi być umieszczona w klasie statycznej (sama metoda też musi być statyczna), a po drugie, klasa nie może być zagnieżdżona. W tym momencie można przekształcić dowolną metodę w metodę rozszerzającą. W tym celu należy na liście parametrów metody umieścić (jako pierwszy) parametr postaci: t h i s Ń azw aTypu n azw a P a ra m e tru gdzie Nazwa Typu określa typ, do którego chcemy dodać metodę rozszerzającą (nazwa Parametru może być dowolna). Ten parametr stanowi bezpośrednie (i jedyne) powiązanie utworzonej metody z typem oryginalnym. Należy zwrócić uwagę, że mimo istnienia parametru w deklaracji metody nie podaje się go przy wywołaniu. Można powiedzieć, że wywołanie metody za pomocą konkretnego obiektu powoduje automatyczne „przekazanie" go w ramach pierwszego parametru metody.
Tablice in fo rm a ty c z n e . C # . W yd an ie II Klasa Enumerable
Klasa Enum erabl e wykorzystuje mechanizm metod rozszerzających w celu udostępnienia bogatego zbioru funkcji dla Idas kolekcji. Dzięki tej klasie wszystkie kolekcje, które implementują interfejs IE n u m e ra b l e, mogą korzystać z wymienionych poniżej metod (i wielu innych). Opisane metody są bardzo często wykorzystywane również w języku LINQ, który jest przedstawiony w kolejnej sekqi. Warto zwrócić uwagę, że mimo dość skomplikowanych sygnatur stosowanie rozważanych metod jest znacznie prostsze. b oo l A l 1 ( < T S o u r c e > ( t h i s IE n u m e r a b le < T S o u rc e > s o u r c e , F u n c < T S o u r c e , b o o l> p r e d i c a t e ) — zwraca t r u e , jeśli wszystkie elementy kolekcji spełniają podany warunek (predykat — funkcję logiczną), b oo l A n y < T S o u r c e > ( t h is IE n u m e r a b le < T S o u rc e > s o u r c e , F u n c < T S o u r c e , b o o l> p r e d i c a t e ) — zwraca t r u e , jeśli którykolwiek z elementów kolekcji spełnia podany warunek (predykat — funkcję logiczną), d o u b le A v e r a g e ( t h i s IE n u m e r a b le < d o u b le > so u r c e ) — oblicza średnią arytmetyczną elementów kolekcji typu d o u b l e. Istnieją też wersje przeciążone dla typów i n t, i n t6 4, f 1 o a t, d ę c i m a i, a talie ich odmian nullowalnych. IE n u m e r a b le < T S o u rc e > C o n c a t < T S o u r c e > ( t h is IE n u m e r a b le < T S o u rc e > f i r s t , IE n u m e ra b l e < T S o u rc e > se c o n d ) — łączy dwie kolekcje w jedną. IE n u m e r a b le < T S o u rc e > D is t i n c t < T S o u r c e > ( t h i s IE n u m e r a b le < T S o u rc e > s o u r c e , I E q u a l i ty C o m p a r e r < T S o u r c e > c o m p a re r) — zwraca kolekcję, która zawiera elementy z oryginalnej kolekcji z pominięciem duplikatów. Do porównywania elementów jest wykorzystywany obiekt co m pa re r. T S o u rce F i r s t O r D e fa u lt < T S o u r c e > (t h is IE n u m e ra b l e < T S o u rc e > s o u r c e ) — zwraca pierwszy element podanej kolekcji lub element domyślny (domyślna wartość dla typów prymitywnych lub n ul 1 dla typów referencyinych), jeśli kolekcja jest pusta. IO r d e re d E n u m e r a b le < T S o u r c e > O rd e rB y < T S o u rce , T K e y > (t h is IE n u m e r a b le < T S o u rc e > s o u r c e , F u n c < T S o u r c e , T K e y > k e y S e l e c t o r ) — zwraca posortowaną kolekcję. Do sortowania są używane elementy typu TKey. Elementy te są wybierane z obiektów kolekcji za pomocą funkcji k e y S e le c t o r . IE n u m e r a b le < in t > R a n g e ( in t s t a r t , i n t n) — zwykła, statyczna metoda klasy Enum erabl e, która zwraca kolekcję n liczb całkowitych od liczby s t a r t . IE n u m e r a b le < T S o u rc e > R e v e r s e < T S o u r c e > ( t h is IE n u m e r a b le < T S o u rc e > s o u r c e ) — zwracakolekcję o odwróconej kolejności elementów w porównaniu do kolekcji oryginalnej. IE n u m e r a b le < T R e s u lt > S e le c t < T S o u r c e , T R e s u l t > ( t h i s IE n u m e r a b le < T S o u rc e > s o u r c e , F u n c < T S o u r c e , T R e s u lt > s e l e c t o r ) — zwraca projekcję podanej kolekcji zgodnie z określonymi warunkami, tj. wybiera określony fragment każdego elementu (typu T R e s u l t) i wstawia go do wynikowej kolekcji. IE n u m e r a b le < T S o u rc e > S k i p < T S o u r c e > ( t h i s IE n u m e r a b le < T S o u rc e > s o u r c e , i n t n) — zwraca wszystkie elementy kolekcji oryginalnej, począwszy od tego o indeksie n. IE n u m e r a b le < T S o u rc e > T a k e < T S o u r c e > ( t h is IE n u m e r a b le < T S o u rc e > s o u r c e , i n t n) — zwraca n elementów kolekcji, począwszy od pierwszego ze źródłowej kolekcp. Często wykorzystywana w połączeniu z metodą S k i p ( ) . IE n u m e r a b le < T S o u rc e > W h e r e < T S o u r c e > ( t h is IE n u m e r a b le < T S o u rc e > s o u r c e , F u n c < T S o u r c e , b o o l> p r e d i c a t e ) — tworzy kolekcję złożoną z elementów oryginalnej kolekcp, dla których funkcja logiczna (predykat) zwraca wartość t rue.
LINQ LINQ to specjalny składnik platformy NET, który umożliwia tworzenie skomplikowanych zapytań umożliwiających wyrafinowany dostęp do danych bezpośrednio w kodzie języka C# (i innych języków dostępnych na platformie NET). Zapytania te przypominają nieco język SQL, ale mogą być stosowane wobec różnych źródeł danych (zwykłych kolekcji, dokumentów XML, ale również baz danych) itd. Dużą rolę odgrywają też metody opisane w poprzedniej sekcji, które w praktyce gwarantują funkcjonalność podobną do języka SQL. Najprostsze zapytanie LINQ składa się z kilku części: i n t [ ] t a b l i c a = new i n t [] { 3 , 4 , 5 } ; v a r t e k s t y = fro m p i n t a b l i c a s e le c t p .T o S t r in g O ; Pogrubiony fragment powyższego kodu to zapytanie LINQ. Ze względu na długość i strukturę zapytania LINQ są zazwyczaj zapisywane w kilku wierszach. Wyniki zapytania (na|częściej kolekcje danych) najłatwiej jest zapisać do zmiennej o nieokreślonym typie, ponieważ typy wyników zwracanych przez zapytania LINQ są często skomplikowane i wydłużają kod, a nie wnoszą nic do funkcjonalności wyników. Pierwszą część praktycznie wszystkich zapytań LINQ stanowi część fro m X in Y, w której określamy kolekcję źródłową (Y) i alias pojedynczego elementu kolekcji, na którym są wykonywane operacje (X). W powyższym przykładzie każda liczba z tablicy jest konwertowana do łańcucha znaków, który wchodzi w skład nowej kolekcji. Zapytania LINQ są bardzo często wykonywane na bardziej złożonych obiektach, np. pochodzących z bazy danych. Taką sytuację symuluje poniższy przykład: v a r t a b l i c a = new [] { new ( Im ię = " J a n " , N a z w isk o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" } } ; v a r im io n a = fro m p i n t a b l i c a s e le c t p .Im ie ;
Do testów wykorzystujemy tablicę obiektów o dynamicznie tworzonych właściwościach. Dzięki temu me musimy myśleć 0 deklaracji klasy dla takich danych. Następnie w zapytaniu LINQ wykonujemy klasyczną operację na danych — projekcję, czyli wybór niektórych właściwości obiektów z kolekcji. v a r t a b l i c a = new [ ] { new { Im ię = " J a n " , N a z w isk o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" }}; v a r ja n o w ie = fro m p i n t a b l i c a w h e re p . I m i e == „ J a n " s e l e c t p; Powyższe zapytanie pozwala na wybór tylko obiektów spełniających określone kryterium. Proszę zwrócić uwagę, że klauzula w here jest umieszczona przed klauzulą s e l e c t — nie jest to przypadek. v a r t a b l i c a = new [] { new { Im ię = " J a n " , N a z w isk o = " K o w a l s k i " } , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" )); v a r p ie r w s z y = (fro m p i n t a b l i c a s e le c t p ) . T a k e ( l) ; Wyniki zapytania mogą być traktowane jako obiekt interfejsu 1 Enu m erab l e, dzięki czemu nie ma problemu, aby wywołać bezpośrednio jego metody. W powyższy sposób możemy pobrać określoną liczbę początkowych elementów kolekcji, a dodając metodę S k i p ( ) , możemy w bardzo łatwy sposób zasymulować mechanizm stronicowania: v a r t a b l i c a = new [ ] { new { Im ię = " J a n " , N a z w isk o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" )); v a r d r u g i = (fro m p i n t a b l i c a s e le c t p ) . S k ip ( l ) . T a k e ( l ) ; Sortowanie wyników jest możliwe za pomocą operatora orderby: v a r t a b l i c a = new [] { new { Im ię = " J a n " , N a z w is k o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" )); v a r p o so rto w a n e = fro m p i n t a b l i c a o r d e r b y p .Im ie d e s c e n d in g s e l e c t p ; W ten sposób obiekty zostaną posortowane malejąco po imieniu. Przy okazji warto skorzystać z mechanizmu, który pozwala na nieco większą elastyczność niż w przypadku sztywnych klauzul języka LINQ. Klauzule te bezpośrednio wykorzystują metody API kolekcji, które można wywoływać samemu. Przepisanie powyższego przykładu nieco zmieni efekt: v a r t a b l i c a = new [] { new { Im ię = " J a n " , N a z w isk o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" )); v a r p o so rto w a n e = (fr o m p i n t a b l i c a s e le c t p ). O r d e r B y D e s c e n d in g (x => x . I m ię ) ; W ten sposób można uzyskać identyczny efekt, co w poprzednim przykładzie, otrzymując pełnię możliwości wyrażeń lambda. Ponadto stosowanie łańcucha wywołań pokazuje kolejność wykonywanych operacji. Nic nie stoi na przeszkodzie, aby projekcja (operacja s e l e c t ) powodowała pobranie nie całych obiektów (tudzież ich pojedynczych właściwości), ale zupełnie nowych obiektów: v a r t a b l i c a = new [] { new { Im ię = " J a n " , N a z w isk o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j " , N a z w isk o = "Nowak" }}; v a r nowy = (fr o m p i n t a b l i c a s e l e c t new { P se ud on im = p .N a z w is k o + p .Im ie ) ) ; W ten sposób uzyskuje się obiekt nowego, nieokreślonego typu, który zawiera jedną właściwość — P seud on im , powstałą na skutek konkatenacji dwóch właściwości z oryginalnego elementu. Nieco bardziej skomplikowaną operację stanowi grupowanie. Grupowanie pozwala na podział oryginalnej kolekcji na pewną liczbę zbiorów, w których pewna cecha ma identyczną wartość: v a r t a b l i c a = new [ ] { new { Im ię = " J a n " , N a z w isk o = " K o w a l s k i " ) , new { Im ię = " A n d r z e j" , N a z w isk o = "Nowak" } , new { Im ię = 'J a n " , N a z w isk o = "Nowak" } } ; v a r z gru p o w a n e = (fr o m p i n t a b l i c a g ro u p p b y p .N a z w is k o i n t o g s e l e c t new { N a z w isk o = g .K e y , O so b y = g } ) ; Efektem operacji grupowania jest obiekt g, Obiekt ten reprezentuje pojedynczą grupę (zbiór elementów z oryginalnej kolekcji o tej same| wartości pewnej cechy— w tym przypadku nazwiska). Korzystając z właściwości Key, możemy ustalić to nazwisko, zaś sam obiekt to po prostu kolekcp elementów o danym nazwisku. W klauzuli s e l e c t nieco przekształcamy zgrupowany zbiór, aby łatwiej można było go wykorzystywać w dalszej części kodu. Ostatnią operacją, którą omówimy, jest złączanie kolekcji (ang. join). v a r im io n a = n ew [] { new { ID = 1, Im ię = " J a n " ) , new ( ID = 2 , Im ię = " A n d r z e j" } } ; v a r f in a n s e = n ew O ( new { ID = 1, Z a r o b k i = 5 0 0 0 .0 } , new { ID = 2 , Z a r o b k i = 7 0 0 0 .0 } } ; v a r zgru p o w a n e = (fr o m i i n im io n a j o i n f i n f in a n s e on i . I D e q u a ls f . I D s e l e c t new ( i . I m i ę , f .Z a r o b k i } ) ; Kolekcje imiona i finanse reprezentują dwie kolekcje z bazy danych, które pozostają ze sobą w relacji jeden do jednego. To, co łączy obie kolekcje, to ID. Dzięki operacji złączenia jesteśmy w stanie połączyć ze sobą identyfikatory obu kolekcji, a co za tym idzie — możemy wstawić do jednego rekordu informację o imionach i zarobkach poszczególnych pracowników. Gdyby w grę wchodziła relacja jeden do wielu (pracownik mógłby na przykład dysponować wieloma pensjami), to zostałoby zwróconych wiele elementów, w których imię byłoby to samo, a zarobki — różne.
KOMPONENTY GRAFICZNE W poniższym zestawieniu znajdują się najważniejsze właściwości i metody wybranych komponentów wizualnych dostępnych na platformie .NET. Dziedziczą one po klasie C o n t r o l, dlatego na początku najlepiej jest omówić elementy tej klasy — jako klasy bazowej.
Właściwości klasy Control b oo l A l 1 owD ro p — określa, czy kontrolka może wykonywać operacje drag-and-drop ( t r u e — może, f a l se — nie może). S y s t e m . D raw i n g . C o lo r B a c k C o l o r — określa kolor tla kontrolki, najczęściej wypełniającego dużą jej część (tlo przycisku, etykiety). S y s t e m .D r a w i n g . R e c t a n g le C l i e n t R e c t a n g le ! — zwraca rozmiar kontrolki bez dodatkowych, a koniecznych elementów, takich jak paski przewijania, paski menu, ramki itd. b oo l C o n t a i n s Fo c u s — określa, czy dany komponent (bądź któreś z jego komponentów-dzieci) jest aktywny (fokusowany; t r u e — tak, f a l se — nie). S y s t e m . Wi n d o w s. F o r m s . C o n te x t M e n u S tr i p C o n te x t M e n u S tr i p — określa menu kontekstowe, przypisane do danej kontrolki. Zwraca n u l i , jeśli nie zostało dodane żadne menu. S y s t e m .W in d o w s .F o r m s .C o n t r o l[] C o n t r o ls — określa listę kontrolek, które należą do danej kontrolki (kontrolekdzieci). S yste m .W i n d o w s. F o r m s . D o c k S t y l e D ock — określa sposób wypełniania komponentu-rodzica (np. formatki) przez kontrolkę. Domyślnie brak wypełnienia (rozmiar zgodny z właściwością S i z e kontrolki), b oo l E n a b le d — określa, czy użytkownik jest w stanie korzystać z kontrolki (t ru e — tak, f a l s e — nie). Wyłączenie kontrolki nie jest równoważne z jej zniknięciem z formatki b oo l In v o k e R e q u i re d — określa, czy inne wątki muszą używać metody I nvo ke ( ) , aby móc w swoim działaniu korzystać z komponentu (t r u e — muszą, f a l s e — nie). S y s t e m . D raw i n g . P o i n t L o c a t io n — określa umiejscowienie komponentu w odniesieniu do komponentu-rodzica. S y ste m .W i n do w s. F o rm s . P a d d in g M a rgi n — określa margines kontrolki — odstęp między nią a jej komponentemrodzicem. S yste m .W i n do w s. F o rm s . P a d d in g P a d d i ng — określa odstęp między granicami kontrolki a jej treścią (np. opisem przycisku). S y s t e m . Wi n do w s. Form s . S i z e S i z e — określa rozmiar kontrolki. S t r i ng T e x t — określa tekst, wyświetlany przez dany komponent (sposób wyświetlania zalety od komponentu), b oo l V i s i b l e — określa, czy komponent jest widoczny (t r u e — tak, f a l se — nie).
Metody klasy Contro! S y s t e m .D r a w i n g .G r a p h i c s C r e a te G r a p h i c s () — tworzy obiekt klasy G ra p h i c s , dzięki któremu można wykonywać operacje graficzne na kontrolce. v o id D o D ra g D ro p O — rozpoczyna operację drag-and-drop. S y s t e m .W in d o w s .F o r m s .Form F in d F o r m ( ) — zwraca obiekt formatki, na której znajduje się kontrolka. S yste m .W i n do w s. F o rm s . C o n t r o l G e t C h i1d A tP o i n t (S y s t e m .D r a w i n g . P o i n t p) — zwraca kontrolkę-dziecko znajdującą się w podanym punkcie, v o id R e f r e s h ( ) — odrysowuje kontrolkę na ekranie, v o id S e l e c t ( ) — uaktywnia kontrolkę.
Zdarzenia klasy Contro! e v e n t E v e n t H a n d le r C l i c k — zachodzi w momencie kliknięcia myszą obszaru kontrolki. e v e n t D r a g E v e n tH a n d le r D ra gD ro p — zachodzi, gdy operacja drag-and-drop zostaje zakończona. e v e n t D ra g E v e n tH a n d l e r D ra g E n t e r — zachodzi, gdy kursor w trakcie operacji drag-and-drop znajdzie się w obszarze kontrolki. e v e n t E v e n t H a n d le r D ra g L e a v e — zachodzi, gdy kursor w trakcie operacji drag-and-drop opuszcza kontrolkę, e v e n t D ra g E v e n tH a n d l e r D r a g O v e r — zachodzi w trakcie przesuwania kursora w czasie operacji drag-and-drop nad kontrolką. e v e n t E v e n t H a n d le r E n t e r — zachodzi w momencie aktywacji kontrolki. e v e n t G iv e F e e d b a c k E v e n t H a n d le r G iv e F e e d b a c k — zachodzi w trakcie operacji drag-and-drop. e v e n t K e y E v e n t H a n d le r Key Down — zachodzi w momencie naciśnięcia klawisza, e v e n t K e y P r e s s E v e n t H a n d le r K e y P r e s s — zachodzi, gdy jest naciśnięty klawisz znakowy, tj. nieposiadający specjalnego znaczenia (jak np. Enter, spacja, TAB), e v e n t K e y E v e n t H a n d le r Key Up — zachodzi w momencie zwolnienia klawisza. e v e n t M o u se Ev en tH a n d l e r Mo u seDown — zachodzi, gdy nad kontrolką zostanie wciśnięty przycisk myszy, e v e n t E v e n t H a n d le r M ouseHover — zachodzi, gdy kursor spoczywa nad kontrolką dłużej, raz określono we właściwości S y s te m ln fo r m a tio n .M o u s e H o v e r T im e . e v e n t M o u se Ev en tH a n d l e r MouseMove — zachodzi, gdy kursor porusza się nad kontrolką, e v e n t M o u se Ev en tH a n d l e r MouseUp — zachodzi, gdy przycisk myszy zostaje zwolniony, e v e n t E v e n t H a n d le r Move — zachodzi w trakcie przemieszczania kontrolki. e v e n t P a in t E v e n t H a n d le r P a in t — zachodzi w momencie odrysowania kontrolki, e v e n t E v e n t H a n d le r R e s i z e — zachodzi w trakcie zmiany rozmiarów kontrolki.
Komponenty wizualne Poniższe zestawienie zawiera opis komponentów dziedziczących po klasie C o n t r o ! . Wszystkie one należą do przestrzeni nazw S y s t e m . Wi n do w s. Form s. W niektórych przypadkach jest zaznaczona informacja o dziedziczeniu danego elementu klasy.
Button
Przycisk najczęściej wykorzystywany do zatwierdzenia wykonywanych wcześniej operacji.
Właściwości klasy Button S y ste m .W i n do w s. F o rm s. F Ia t B u t t o n A p p e a r a n c e F I a tA p p e a r a n c e — precyzuje wygląd i zachowanie przycisku, jeśli właściwość F I a t Ś t y l e ma wartość F I a t. S y ste m .W i n do w s. F o rm s. F I a t S t y l e F I a t S t y l e — określa sposób, w jaki jest rysowany przycisk (domyślnie S ta n d a rd ). S y s t e m .W in d o w s .F o r m s .Im age Im age — określa obrazek, który jest wyświetlany na przycisku (właściwość F I a t S t y l e nie może mieć wartości System ). S t r i ng T e x t (odziedziczona z klasy C o n t r o l) — określa tekst wyświetlany na przycisku.
Metody klasy Button v o i d P e rfo rm C l i c k () — generuje zdarzenie C l i c k dla danego przycisku.
Zdarzenia klasy Button e v e n t E v e n t H a n d le r D o u b l e c l i c k — zachodzi, gdy użytkownik kliknie dwukrotnie przycisk,
CheckBox Pole do zaznaczenia, zawierające opis tekstowy W jednej grupie komponentów C h e c k B o x może być zaznaczonych więcej pól niż jedno.
Właściwości klasy CheckBox S y s t e m . Wi n do w s. Form s .A p p e a ra n c e — określa wygląd pola. b oo l A u to C h e c k — określa, czy pole automatycznie zmienia stan zaznaczenia przy kliknięciu (t r u e — tak, f a l se — nie). S y ste m .W i n do w s. F o rm s. C h e c k S t a t e C h e c k S t a t e — zwraca stan, w jakim znajduje się pole. b oo l C h e cke d — zwraca stan, w jakim znajduje się pole ( t ru e , jeśli właściwość C h e c k S t a t e ma wartość C h e cke d lub In d e t e r m i n a te , f a l se jeśli U nchecked), b oo l T h r e e S t a t e — określa, czy pole może przybierać trzy stany zaznaczenia (t r u e — tak, f a l se — nie). Nawet jeślita właściwość ma wartość f a l se, pole może przybrać początkową wartość In d e t e r m i n a te (niedostępną w trybie dwustanowym).
Zdarzenia klasy CheckBox e v e n t E v e n t H a n d le r C h e cke d C h an ge d — zachodzi, gdy zmienia się wartość właściwości Ch ecked , e v e n t E v e n t H a n d le r C h e c k S ta te C h a n g e d — zachodzi, gdy zmienia się wartość właściwości C h e c k S t a t e (także w momencie zmiany z wartości In d e t e r m i n a te na C h e c k e d — wtedy nie zachodzi zdarzenie CheckedChanged).
ComboBox Komponent łączący listę elementów i pole tekstowe.
Właściwości klasy ComboBox S yste m .W i n d o w s. F o rm s. A utoCom pl eteM ode AutoCom pl eteM ode — określa sposób uzupełniania tekstu wpisywanego w pole tekstowe. S y s t e m . Wi n do w s. F o rm s. DrawMode DrawMode — określa sposób rysowania elementów rozwijanej listy. S y ste m .W i n do w s. F o rm s. C o m b o B o x S ty le D ro p D o w n S ty l e — określa styl wyświetlania rozwijanej listy (m.in. czy użytkownik może wprowadzić tekst do pola tekstowego). S yste m .W i n d o w s. F o rm s. O b j e c t C o l1e c t i on Ite m s — określa elementy rozwijanej listy, i n t S e le c t e d ln d e x — określa numer zaznaczonego elementu z listy. O b je c t S e le c t e d lt e m — zwraca bądź ustawia zaznaczony element z rozwijanej listy (należący do właściwości I tems). S t r i ng S e l e c t e d T e x t — zwraca bądź ustawia tekst znajdujący się w polu tekstowym.
Metody klasy ComboBox i n t F i n d S t r i n g ( S t r i n g s ) — zwracaindeks pierwszego elementu rozwijanej listy, który zawiera łańcuch s (od początku elementu).
Zdarzenia klasy ComboBox e v e n t D ra w Ite m E v e n t H a n d le r D ra w lte m — zachodzi, gdy odrysowywana |est rozwijana lista, jeśli właściwość DrawMode jest ustawiona na wartość inną niż N o rm a l. e v e n t E v e n t H a n d le r DropDown — zachodzi w momencie rozwijania listy. e v e n t E v e n t H a n d le r D ro p D o w n C lo se d — zachodzi w momencie zwijania listy, e v e n t M e a s u r e lt e m E v e n tH a n d le r M e a su re lte m — zachodzi przed odrysowywaniem listy, jeśli właściwość DrawMode jest ustawiona na wartość inną niż N orm al. e v e n t E v e n t H a n d le r S e le c t e d ln d e x C h a n g e d — zachodzi w momencie zmiany zaznaczonego elementu.
ContextMenuStrip
Rozwijane menu kontekstowe (dołączane do innych kontrolek).
Właściwości klasy ContextMenuStrip S yste m .W i n d o w s. F o rm s. T o o l S t r i p lte m C o l 1 e c t i on Ite m s — określa listę elementów tworzących menu kontekstowe. S y s t e m .W in d o w s .F o rm s. T o o l S t r i p L a y o u t S t y le L a y o u t S t y 1 e — określa sposób ułożenia pozycji menu kontekstowego. S yste m .W i n do w s. F o rm s. T o o l S t r i pRenderM ode RenderM ode — określa sposób rysowania menu kontekstowego, b o o l Show Im ageM argi n — określa, czy elementy menu zawierają miejsce na obrazki (t r u e — tak, f a l se — nie). S y ste m .W i n do w s. F o r m s .C o n tr o ! S o u r c e C o n t r o l — określa kontrolkę, której kliknięcie spowodowało wyświetlenie menu kontekstowego. Ciąg dalszy na str. 5
Tablice in fo rm a ty c z n e . C # . W yd an ie II Metody klasy ContextMenuStrip v o id S h o w (S y s t e m .D r a w in g .P o in t p) — wyświetla menu kontekstowe w danym punkcie.
Zdarzenia klasy ContextMenuStrip e v e n t E v e n t H a n d le r C lo s e d — zachodzi tuż po zamknięciu menu kontekstowego. e v e n t T o o l S t r i pD ro pD ow nC lo s i n gEv e n tH a n d l e r C l o s i ng — zachodzi w trakcie zamykania menu kontekstowego (można tę operację zablokować). e v e n t E v e n t H a n d le r Opened — zachodzi tuż po otwarciu menu kontekstowego. e v e n t C a n c e lE v e n t H a n d le r O p e n in g — zachodzi w momencie otwierania menu kontekstowego (można tę operację zablokować).
DateTimePicker Kontrolka umożliwiająca pobieranie i wybieranie daty za pomocą wbudowanego kalendarza
Właściwości klasy DateTimePicker b oo l C h e cke d — określa, czy kalendarz wyświetla poprawną datę i czy jest włączony (możliwa jest zmiana daty; t ru e — tak, f a l s e — nie). S t r i ng Cu sto m F o rm at — umożliwia podanie własnego formatu wyświetlania daty przy podaniu określonych znaczników (jeśli właściwość Fo rm at ma wartość Custom). S y ste m .W in d o w s. F o rm s . D a t e T im e P ic k e r Fo rm a t Fo rm at — określa sposób wyświetlania daty. b oo l ShowUpDown — określa, czy wyświetlane są przyciski umożliwiające zmianę daty przy użyciu strzałek, a nie kalendarza ( t r u e — tak, f a l s e — nie). D a t e T i me V a lu e — zwraca datę wybraną za pomocą kalendarza.
Label Etykieta tekstowa; może wyświetlać również grafikę.
Właściwości klasy Label b oo l A u t o S iz e — określa, czy wymiary etykiety będą dostosowywane do wyświetlanego tekstu (t r u e — tak, f a l s e — nie). S yste m .W i n do w s. F o r m s . B o r d e r S t y l e B o r d e r S t y l e — określa rodzaj obramowania etykiety. S y s t e m . D r a w in g . Im age Im age — określa obrazek wyświetlany w etykiecie (jako tlo dla napisu). S y s t e m . D raw i n g . S i z e Maxi mumSi z e (odziedziczona z klasy C o n t r o l) — określa maksymalny rozmiar pola, w którym jest wyświetlana etykieta. Umożliwia to kontrolę nad sposobem wyświetlania tekstu (np. w ilu linijkach zostanie wyświetlony tekst). Właściwość ta ma pierwszeństwo przed właściwością A u t o S iz e . S t r i n g T e x t — określa tekst etykiety. S y s t e m .D r a w i n g .C o n t e n t A l ig n m e n t T e x t A l i gn — określa wyrównanie tekstu etykiety.
ListBox Wybieralna lista elementów.
Właściwości klasy ListBox i n t C o l umnWidth — określa szerokość kolumn w trybie wielokolumnowym. b oo l H o r i z o n t a l S c r o l 1 b a r — określa, czy (jeśli jest to konieczne) jest wyświetlany poziomy pasek przewijania (t r u e — tak, f a l s e — nie). b oo l S c r o l l A l w a y sV i s i b l e — określa, czy pasek (paski) przewijania są zawsze widoczne (t r u e — tak, f a l se — nie), b o o l Mul t i C o l umn — włącza lub wyłącza tryb wielokolumnowy listy. W tym trybie elementy listy są wyświetlane w taki sposób, aby nie aktywować pionowego paska przewijania (po maksymalnym wypełnieniu pierwszej kolumny elementy dodawane są do kolumn następnych). S y s t e m .W in d o w s .F o rm s. S e le c t e d O b je c t C o l 1 e c t i on S e le c t e d lt e m s — zwraca wszystkie zaznaczone elementy listy, jeśli właściwość S e l e c t i onMode ma wartość Mul t i S im p l e lub M u lt i E xte n d e d . S yste m .W i n d o w s. F o rm s . S e l e c t i onMode S e l e c t i onMode — określa sposób, w jaki użytkownik może wybrać element(y) listy.
Metody klasy ListBox v o id C l e a r S e l e c t e d ( ) — usuwazaznaczenie ze wszystkich zaznaczonych elementów listy, b oo l G e t S e l e c t e d ( i n t i n d e x ) — zwracatr u e , jeśli element o danym indeksie jest zaznaczony ( f a l se w przeciwnym razie), v o id S e t S e l e c t e d ( i n t in d e x , bool w a r t o ś ć ) — ustawia zaznaczenie danego elementu na określoną wartość.
MenuStrip Menu systemowe aplikacji widoczne na górze formatki.
Właściwości klasy MenuStrip S yste m .W i n d o w s. F o rm s. T o o l S t r i p lte m C o l l e c t i o n Ite m s (odziedziczone z T o o l S t r i p) — przechowuje elementy menu. S yste m .W i n d o w s. F o rm s. T o o l S t r i p T e x t D i r e c t i on T e x tD i r e c t i on (odziedziczone z To o 1 S t r i p) — określa sposób wyświetlania menu (np, horyzontalny, wertykalny).
Metody klasy MenuStrip
S t r i ng Im a g e L o c a t i on — określa lokalizację, z której ma być pobrany obrazek (za pomocą metod Load ( ) — synchronicznie i Lo a d A sy n c ( ) — asynchronicznie). S yste m .W i n d o w s. F o rm s. P i c t u r e B o x S i zeMode Size M o d e — określa sposób wyświetlania obrazka w kontrolce (m.in. w sytuacji, gdy rozmiar obrazka jest różny od rozmiaru kontrolki). S y s t e m .D ra w in g . Im age I n i t i a l Im age — określa obrazek, który będzie wyświetlany w trakcie ładowania się głównego obrazka. b oo l Wa i 10 n Lo a d — określa, czy obrazek ma być ładowany synchronicznie (tru e ), czy asynchronicznie ( f a 1 s e).
Metody klasy PictureBox v o id Load ( ) — wczytuje obrazek synchronicznie. Właściwość Wai tO n Lo a d musi mieć wartość tr u e , v o id Lo a d A sy n c ( ) — wczytuje obrazek asynchronicznie. Właściwość Wai tO nLo a d musi mieć wartość f a l se.
Zdarzenia klasy PictureBox e v e n t A s y n c C o m p le te d E v e n tH a n d le r LoadCompl e t ed — zachodzi, gdy skończy się ładowanie obrazka, e v e n t P r o g r e s s C h a n g e d E v e n t H a n d le r L o a d P r o g re s s C h a n g e d — zachodzi w trakcie procesu pobierania obrazka (tylko asynchronicznie).
ProgressBar Komponent przedstawiający pasek postępu.
Właściwości klasy ProgressBar i n t Maximum — określa maksymalną wartość, jaką może osiągnąć pasek. i n t M in i mum — określa minimalną wartość, jaką może osiągnąć pasek. i n t S te p — określa wartość, o jaką ma zwiększać się postęp przy wykonywaniu metody P e r fo rm S t e p ( ) . i n t V a lu e — określa osiągniętą wartość postępu.
Okna dialogowe Okna dialogowe mają różny wygląd i działanie. Dzięld nim złożone operacje, takie jak np. wybór pliku z dysku, sprowadzają się do wywołania jednej metody. Jednym z najprostszych rodzajów okien dialogowych jest okno wyświetlające wiadomość — M essageB ox.
MessageBox Okno dialogowe umożliwiające zaakceptowanie lub odrzucenie propozycji; posiada bardzo dużo możliwości wyświetlania. Do wyświetlenia okienka wykorzystuje się metodę S how ( ) (ma ona 21 wariantów): S yste m .W i n d o w s. F o rm s. Di a l o g R e s u lt M e s s a g e B o x .S h o w ( S t r in g t y t u ł , S t r i n g o p i s , S y s t e m .W in d o w s .F o rm s. M e ssa g e B o x B u tto n s p r z y c i s k i , S y ste m . Wi n d o w s. F o r m s .M e s s a g e B o x Ic o n i ko n a) M e ssa g e B o x B u tto n s i M e ssage B ox Ic o n są typami wyliczeniowymi; udostępniają wszystkie znane konfiguracje przycisków i Ikon. Typ wyliczeniowy Di a l o g R e s u l t posiada wartości dla wszystkich przycisków, jakie mogą pojawić się w okienku; w zwracanej przez metodę wartości jest określony wybrany przez użytkownika przycisk.
RadioButton Pole do zaznaczenia, zawierające opis tekstowy. W jednej grupie komponentów R a d io B u t to n może być zaznaczone tylko jedno pole.
Właściwości klasy RadioButton S yste m .W i n d o w s. F o rm s .A p p e a ra n c e A p p e a ra n c e — określa wygląd pola (podobnie jak w przypadku komponentu Ch eckB ox). b oo l C h e cke d — określa, czy pole jest zaznaczone (t r u e — tak, f a l se — nie).
Zdarzenia klasy RadioButton e v e n t E v e n t H a n d le r C h e c k e d C h a n g e d — zachodzi, gdy nastąpi zmiana stanu pola.
OpenFileDialog
RichTextBox
Bardzo ważną grupę okien dialogowych stanowią standardowe okna systemu Windows służące do wykonywania określonych czynności. Klasa O p enFi 1 e D i a l og udostępnia okno wyboru pliku.
Pole tekstowe o najbardziej rozbudowanych możliwościach spośród wszystkich kontrolek systemu Windows.
Właściwości klasy RichTextBox
Właściwości klasy OpenFileDialog
b o o l A u to W o r d S e le c t io n — określa, czy możliwe jest zaznaczenie tylko całych wyrazów (t r u e — tak, f a l se — nie), b oo l D e t e c t s U r l s — określa, czy adresy URL mają być automatycznie zamieniane na odnośniki S t r i n g R t f — zwraca zawartość pola tekstowego w formacie RTF S t r i n g S e 1 e c t e d R t f — zwraca aktualnie zaznaczony tekst w formacie RTF. S y s t e m .D r a w i n g . F o n t S e l e c t i o n F o n t — umożliwia zmianę czcionki dla zaznaczonego fragmentu. Zmieniając tę właściwość w sytuacji, gdy jest zaznaczony fragment tekstu, umożliwia się zmianę formatowania (podobnie jak inne właściwości ma|ące w nazwie słowo S e l e c t i on). S t r i n g T e x t — zwraca zawartość pola tekstowego, b oo l W ordwrap — określa, czy tekst w kontrolce jest zawijany ( t r u e — tak, f a l s e — nie). f 1 o a t Z o o m F a c to r — określa stopień powiększenia tekstu (większy od 1 — tekst zostaje powiększony; mniejszy od 1 — tekst zostaje pomniejszony).
b o o l C h e c k F i 1 e E x i s t s — określa, czy w przypadku wprowadzenia nazwy nieistniejącego pliku zostanie wyświetlone ostrzeżenie (t ru e — tak, f a l s e — nie). S t r i n g F i l eName (odziedziczona po klasie F i 1 e D i a l og) — zwraca nazwę wybranego pliku. S t r i ng [] F i l eNames (odziedziczona po klasie F i 1 eDi a l og) — zwraca nazwy wybranych plików (jeśli właściwość Mul t i S e l e c t ma wartość tru e ). S t r i ng F i 1 t e r (odziedziczona po klasie F i l eDi a l og) — określa rodzaje filtrów, według których wyświetlane są jedynie pliki o danym rozszerzeniu. b oo l Mul t i S e l e c t — określa, czy jest możliwy wybór wielu plików (t r u e — tak, f a 1 s e — nie).
Metody klasy OpenFileDialog S yste m .W i n do w s. F o r m s .D i a l o g R e s u lt ShowDi a lo g ( ) (odziedziczona po klasie CommonDi a l og) — wyświetla okienko dialogowe I zwraca rodza| wybranego przycisku.
Metody klasy RichTextBox v o id L o a d F i l e f s t r i n g n azw a , S y ste m . W ind o w s. F o rm s. R i c h T e x tB o x S tr e a m T y p e t y p ) — wczytuje tekst z pliku, uwzględniając podany typ dokumentu (istnieje możliwość wyboru między czystym tekstem a odmianami formatu RTF). i n t G e t L in e F r o m C h a r In d e x ( in t in d e x ) — zwraca numer linii, w której znajduje się znak o podanym indeksie, v o id S a v e F i 1 e ( S t r i n g n azw a , S y ste m . Wi n do w s. F o r m s . R i c h T e x tB o x S tr e a m T y p e t y p ) — zapisuje zawartość pola tekstowego do pliku, uwzględniając podany typ (jak w przypadku metody Load F i 1 e ( ) ). i n t F i n d ( S t r i n g 1 a n c u c h ) — zwracapoczątek (indeks pierwszego znaku) fragmentu pola tekstowego, który zawiera dany łańcuch.
PrintDialog Ten rodza| okna dialogowego jest wyświetlany przed rozpoczęciem drukowania dokumentów.
Właściwości klasy PrintDialog S y s t e m . D raw i n g . P r i n t i n g . P r i n tD ocum ent Docum ent — określa dokument przeznaczony do drukowania. S y ste m .W in d o w s. F o rm s. P r i n t e r S e t t i n gs P r in t e r S e t t i n g s — określa ustawienia drukarki, jakie zostaną wykorzystane do drukowania.
Metody klasy PrintDialog S y s te rn .W in d o w s .F o r m s .D i a l o g R e s u lt ShowDi a l og ( ) (odziedziczona po klasie CommonDi a l og) — wyświetla okienko dialogowe i zwraca rodzaj wybranego przycisku. Pozostałe okna dialogowe mają podobne właściwości i metody; są to: o C o l o r D i a l og — okienko do wyboru koloru; • F o l d e r B ro w s e rD i a l og — okienko do wyboru katalogu; o F o n tD i a lo g — okienko do wyboru czcionki, • P a g e S e t upD i a 1 o g — okienko do zmiany ustawień strony (w procesie drukowania); o S a v e F i 1 eD i a l og — okienko do wyboru nazwy pliku do zapisania.
Zdarzenia klasy RichTextBox e v e n t L i n k C lic k e d E v e n t H a n d le r L i n k C l i ck e d — zachodzi w momencie kliknięcia przez użytkownika odnośnika. e v e n t E v e n t H a n d le r S e le c t io n C h a n g e d — zachodzi, gdy nastąpi zmiana obszaru zaznaczenia.
TreeView
PictureBox
Właściwości klasy TreeView
S y s t e m . D r a w in g .Im age Im a g e — określa obrazek, który będzie wyświetlany
Zdarzenia klasy TreeView e v e n t T r e e V ie w E v e n t H a n d le r A f t e r C o l 1 a p se — zdarzenie zachodzi po zwinięciu gałęzi. e v e n t T r e e V ie w E v e n t H a n d le r A ft e r E x p a n d — zdarzenie zachodzi po rozwinięciu gałęzi. e v e n t T r e e V ie w E v e n t H a n d le r A f t e r S e l e c t — zdarzenie zachodzi po zaznaczeniu gałęzi, e v e n t T r e e V ie w E v e n t H a n d le r B e fo r e C o l 1 a p s e — zdarzenie zachodzi przed zwinięciem gałęzi. e v e n t T r e e V ie w E v e n t H a n d le r B e fo re E x p a n d — zdarzenie zachodzi przed rozwinięciem gałęzi. e v e n t T r e e V ie w E v e n t H a n d le r B e f o r e S e le c t — zdarzenie zachodzi przed zaznaczeniem gałęzi. e v e n t T re e N o d e M o u se C lic k E v e n t H a n d le r No d eMo u s e C 1 i c k — zachodzi w momencie kliknięcia gałęzi.
Metody klasy ProgressBar
Komponent wyświetlający swoje elementy w postaci rozwijanych gałęzi (z ang. node).
Właściwości klasy PictureBox
Metody klasy TreeView v o i d Co l 1 a p s e A l 1 ( ) — zwija wszystkie gałęzie v o i d E xp a n d A l 1 () — rozwija wszystkie gałęzie. S y s t e m .W in d o w s .F o r m s .Tree N od e G e tN o de A t (P o i n t p) — zwraca gałąź znajdującą się w danym punkcie (współrzędne punktu w odniesieniu do lewego górnego rogu kontrolki). v o id S o r t ( ) — sortuje drzewo za pomocą obiektu określonego we właściwości T r e e V i e w N o d e S o rte r.
v o id In c r e m e n t ( i n t w a r t o ś ć ) — zwiększawartość postępu o podaną wartość. v o id P e r fo rm S t e p ( ) — zwiększa wartość postępu o wartość właściwości S te p .
S yste m .W i n do w s. F o rm s . T o o l S t r i p i tern G e t It e m A t ( S y s t e m .D r a w in g .P o in t p) — zwraca element znajdujący się w danym punkcie.
Komponent umożliwiający wyświetlanie obrazków.
S yste m .W i n do w s. F o r m s .Tree N od e S e l e cte d N o d e — określa aktualnie zaznaczoną gałąź. S yste m .W i n do w s. F o r m s .T ree N o d e TopNode — określa najwyżej znajdującą się w hierarchii i widoczną gałąź, S y s t e m . W ind o w s. F o rm s. T r e e V i e w N o d e S o rte r T r e e V i ew N o de So rt e r — określa obiekt sortujący drzewo.
Wybrane zagadnienia
S yste m .W i n d o w s. F o rm s.T re e N o d e C o l 1 e c t i on N odes — określa całkowitą strukturę gałęzi, jaką posiada kontrolka. S t r i n g P a t h S e p a r a t o r — określa znak lub ciąg znaków służący do oddzielania nazw kolejnych gałęzi przy podawaniu ścieżek dostępu do gałęzi.
W niniejszym podrozdziale znajduje się opis szeregu zagadnień z różnego rodzaju zakresu; każdy opis zawiera listę i krótką charakterystykę używanych klas I interfejsów oraz praktyczny przykład.
5
Korzystanie w wątkach z komponentów Ul
Klasa B a c kgroundWo rke r może być z powodzeniem wykorzystywana w większości operacji wymagających użycia wątków. Problem pojawia się, gdy zachodzi potrzeba skorzystania w metodzie wątku np. z komponentów graficznych. Są one tworzone w głównym wątku aplikacji i z tego względu wątki poboczne nie ma|ą do nich dostępu Można jednak ominąć to zabezpieczenie, korzystając z implementowanego przez wszystkie kontrolki graficzne (pochodne klasy S yste m .W i n d o w s. F o rm s. C o n t r o l) interfejsu I S y n c h r o n iz e ln v o k e .
ISynchronizelnvoke (System. ComponentModel) Najważniejszym elementem interfejsu jest metoda In v o k e () ; O b je c t In v o k e ( D e le g a t e delegacja, O b j e c t [ ] parametry) Metoda ta wywołuje asynchronicznie daną delegację wraz z parametrami. W delegacji należy podać metodę, która dokona zmian w kontrolkach (np. ustawi nową wartość etykiety tekstowej). Aby upewnić się, że dana kontrolka musi być zmieniona za pomocą metody In v o k e , używa się właściwości In v o k e R e q u i red: b o o l In v o k e R e q u i re d — zwraca t r u e , jeśli do zmiany danego komponentu wymagana jest metoda I n vo k e ( ) , f a l se w przeciwnym razie. Wątek można utworzyć w sposób klasyczny — za pomocą klasy T h re a d . W konstruktorze obiektu tej klasy należy podać delegację, jedną z możliwości jest delegacja T h r e a d S t a r t ( ). Konstruktor klasy T h re a d : S y s t e m . T h r e a d in g . T h re a d T h r e a d (S y s te m . T h r e a d in g .T h re a d S t a rt T h r e a d S t a r t) — tworzy obiekt wątku, który wywoła metodę zawartą w delegacji T h r e a d S t a r t .
Przykład: Program wyświetla w etykiecie tekstowej klasy L a b e l (obiekt l a b e l ) aktualny czas. p r i v a t e T h re a d w a te k ; p r i v a t e b oo l w a t e k M a D z ia la c = t r u e ; p r i v a t e d e le g a t e v o id D e le g a c ja (S t r in g w a rto s c ); p r i v a t e v o id F o r m l_ L o a d ( o b je c t s e n d e r , E v e n t A r g s e) ( A p p l i c a t i o n . A p p l i c a t i o n E x i t += new E v e n t H a n d le r ( A p p lic a t io n _ A p p li c a t i o n E x i t ) ; w a te k = new T h re a d (n e w T h r e a d S t a r t (M e t o d a W a t k u )); w a t e k .S t a r t ( ) ; } p r i v a t e v o id U s t a w E t y k i e t e ( S t r i n g w a rto sc) { la b e l.T e x t = w a rto sc; } p r i v a t e v o id M etod aW atku() { w h ile (w a te k M a D z ia la c ) { S t r i n g t e k s t = D a te T im e .U tcN o w . T o S t r in g O ; i f (la b e l.In v o k e R e q u ire d ) { D e le g a t e d e l e g a c j a = new D e le g a c ja ( u s t a w E t y k i e t e ) ; l a b e l . I n v o k e ( d e l e g a c j a , new o b j e c t [] { t e k s t } ) ; } e l se U s t a w E t y k ie t e (t e k s t ); T h r e a d . S le e p ( lO O O ) ; 1 } p r i v a t e v o id A p p l i c a t io n _ A p p lic a t io n E x it ( o b je c t s e n d e r, E v e n t A r g s e) { w a t e k M a D z ia la c = f a l s e ; 1 W momencie załadowania formatki jest tworzony i uruchamiany wątek. Ustawiana jest również metoda obsługi zamknięcia aplikacji. Wynika to z faktu, iż aplikacja systemu Windows zostaje zamknięta dopiero wtedy, gdy wszystkie wątki przez nią utworzone są zamknięte. Jako Iż metoda wątku działa non stop, musi zostać zatrzymana w specjalny sposób (przez zmianę wartości zmiennej w atekM aD zi a l ac). W ten sposób wątek kończy swe działanie i aplikacja może zostać zamknięta. W metodzie MetodaWat ku () pobieramy aktualny czas, a następnie tworzymy delegację. Następnie wywołujemy metodę I nvoke ( ) , uwzględniając parametr, jakim jest łańcuch z aktualnym czasem. Metoda U sta w E ty k i e te () jest odpowiedzialna tylko za zmianę tekstu etykiety — jej nagłówek musi być zgodny z typem delegacji.
Rysowanie
Platforma .NET udostępnia spore możliwości w zakresie rysowania 2D. Wszystkie omawiane w niniejszym podrozdziale klasy i struktury zawarte są w przestrzeni nazw S y s t e m . D raw i ng. Wszelkiego rodzaju funkcje do rysowania linii, luków, figur i innych konstrukcji geometrycznych dostarcza klasa G r a p h i c s . Poniżej znajdują się najpopularniejsze metody uzyskiwania do niej dostępu. • Obiekt tej klasy jest zwracany przez metodę C r e a t e G r a p h ic s ( ) klasy C o n t r o l i jej pochodnych. W tym przypadku uzyskiwany jest dostęp do obszaru danej kontrolki. P a i n t E v e n t A r g s (jako właściwość G ra p h i c s tej klasy) stanowiącą argument delegac|i zdarzenia P a i n t (również w klasie C o n tr o l). Obiekt tej klasy jest udostępniany przez klasy D ra w Ite m E v e n tA r g s lM e a s u re Ite m E v e n tA r g s (jako właściwość Gra p h i c s tych klas), dostępne w zdarzeniach Draw11em i Measu re 1 1 em — są to zdarzenia używane w kontrolkach-listach (np. ComboBox, L i s tB o x ) przy ręcznym rysowaniu elementów list.
Tablice in fo rm a ty c z n e . C # . W yd an ie II Klasa G r a p h ic s udostępnia wiele metod służących do rysowania; poniżej wyszczególniono niektóre z nich: v o id D ra w E ll ip s e ( P e n p io r o , R e c t a n g le p r o s t o k ą t ) — rysuje elipsę ograniczoną przez dany prostokąt przy użyciu określonego rodzaju pióra v o id D ra w lin a g e (Im a g e o b r a z , P o in t p) — rysuje obraz w danym punkcie. v o id D ra w L in e (P e n p io r o , P o in t p l , P o in t p 2) — rysuje linię prostą między dwoma punktami przy użyciu określonego rodzaju piorą. v o id D ra w P o ly g o n (P e n p io r o , P o i n t [] p u n k t y ) — rysu|e wielokąt zlozony z punktów o podanych współrzędnych przy użyciu określonego rodzaju pióra, v o id D ra w R e c t a n g le (P e n p io r o , R e c t a n g le p r o s t o k ą t ) — korzystając z podanej struktury, rysuje prostokąt przy użyciu określonego rodzaju pióra, v o id D r a w S t r i n g ( S t r i n g t e k s t , F o n t c z c i o n k a , Pen p io r o , P o in t F p u n k t) — wypisuje w podanym punkcie tekst. Niektóre z powyższych metod posiadają odpowiedniki rysujące odpowiednie figury z wypełnieniem (zamiast klasy Pen używa się klasy B ru sh ), np: v o id F i l l E l l i p s e ( B r u s h p e d z e l , R e c t a n g le p r o s t o k ą t ) — rysuje przy użyciu określonego rodzaju pióra elipsę z wypełnieniem ograniczoną przez dany prostokąt. W powyższych deklaracjach są używane klasy B ru sh , Fo nt, Pen, które określają sposób rysowania określonych kształtów i napisów. Klasa B ru sh określa sposób rysowania figur wypełnionych (me jest ona wykorzystywana bezpośrednio; korzysta się z jej Idas pochodnych), a Pen niewypełnionych. Klasa F o nt odpowiada za określenie rodzaiu czcionki (m.in. kro|u i rozmiaru). Sposób ich wykorzystania jest zaprezentowany w poniższym przykładzie.
Przykład: Program narysuje na formatce quasi-domek. p r i v a t e v o id F o r m l_ P a in t ( o b j e c t s e n d e r , P a in t E v e n t A r g s e) { G r a p h ic s g = e .G r a p h i c s ; P o i n t [] p u n k ty D a c h = new P o i n t [] { new P o i n t (1 0 0 , 0 ) , new P o in t ( 0 , 7 5 ) , new P o i n t (2 0 0 , 7 5) } ; R e c t a n g le dom = new R e c t a n g le ( 2 5 , 7 5 , 1 5 0 , 1 0 0 ); R e c t a n g le o kn o = new R e c t a n g le (7 5 , 25, 45, 4 5 ); P o in t F p u n k t N a p is u = new P o i n t F ( 7 0 . 0 F , 8 0 . O F ); B ru sh c z e r w o n y P e ln y = new S o l i d B r u s h (C o l o r . R e d ) ; B ru sh c z a r n y P e ln y = new S o lid B r u s h (C o lo r .B 1 a c k ); B ru sh n ie b i e s k o B i a l y = new S y s t e m .D r a w i n g . D raw i n g2 D . L in e a r G r a d ie n t B r u s h (d o m , C o l o r . B lu e , C o lo r .W h it e , 1 8 0 ); B ru sh b ia l y P e l n y = new S o l i d B r u s h (C o lo r .W h i t e ) ; g . F i l l P o ly g o n (c z e r w o n y P e ln y , p u n k ty _ d a c h ); g . F i l l R e c t a n g l e ( c z a r n y P e l n y , d o m ); g . F i 11 E l 1 i p s e ( n i e b i e s k o B i a ly , o k n o ) ; g . D r a w S t r i n g C 'W i t a j ! 11, new F o n t ( " C o u r i e r " , 1 2 . O F ), b ia ł y p e łn y , p un kt n a p is u ); 1 W pierwszej części kodu określamy kształty, jakie będą mieć poszczególne elementy „domu”. Następnie tworzymy obiekty pędzli, po czym przystępujemy do rysowania. Ważne jest, aby umieścić ten kod w zdarzeniu P a i n t formatki (tudzież innego komponentu graficznego), aby było ono odrysowywane za każdym razem (a nie tylko tuz po uruchomieniu).
Korzystanie z systemu plików Przestrzeń"nazw S y s t e m . 10 udostępnia cztery klasy związane z przeglądaniem katalogów i uzyskiwaniem informacji o plikach. Są to klasy Di r e c t o r y , Di r e c t o r y l n f o I F i 1 e, F i 1 e ln f o . Klasy Di r e c t o r y i Di r e c t o r y l n f o różnią się tylko tym, iż klasa Di r e c t o r y całą swą funkcjonalność opiera na metodach statycznych, podczas gdy klasa Di r e c t o r y l n f o oferuje tworzenie obiektów i odwołania do metod za pomocą instancji obiektu (analogicznie wygląda sytuacja w przypadku klas F i 1 e i F i 1 e l n f o — dotyczą one operacji na plikach).
Directory Klasa udostępnia informacje na temat struktury katalogów oraz szczegółowych danych dotyczących poszczególnych katalogów. Wszystkie jej metody są oznaczone jako statyczne. Di r e c t o r y l n f o C r e a t e D i r e c t o r y ( S t r i ng s c i e z k a ) — tworzy katalog o podanej ścieżce, v o id D e l e t e ( S t r i n g ś c i e ż k a , bool p o d k a t a l o g i ) — usuwa katalog o podanej nazwie, jeśli argument p o d k a t a l o g i ma wartość tr u e , zostaną usunięte również podkatalogi i pliki wewnątrz katalogu (jeśli argument ma wartość f a 1 s e, a istnieją podkatalogi bądź pliki, metoda zwróci wyjątek klasy IO E x c e p t i on), b o o l E x i s t s ( S t r i n g ś c i e ż k a ) — zwracat r u e , jeśli podany katalog istnieje, f a 1 s e w przeciwnym wypadku S y s t e m .S e c u r it y .A c c e s s C o n t r o l. D ir e c t o r y S e c u r i t y G e t A c c e s s C o n t r o l ( S t r i n g ś c i e ż k a ) — zwraca systemowe uprawnienia dostępu dla katalogu. D a te T im e G e t C r e a t io n T im e f s t r in g ś c i e ż k a ) — zwraca datę i czas utworzenia katalogu (wyrażony za pomocą czasu lokalnego). S t r i n g Q G e tD i r e c t o r i e s ( S t r i ng ś c i e ż k a ) — pobiera wszystkie nazwy podkatalogów z danego katalogu.
S t r i n g [ ] G e t F i l e s ( S t r i n g ś c i e ż k a ) — pobiera wszystkie pliki z danego katalogu (nie z jego podkatalogów!). S t r i ng [] G e tF i 1 e S y s t e m E n tr i e s ( S t r i ng ś c i e ż k a , S t r i n g w z o r z e c ) — zwraca wszystkie nazwy plików i katalogów z danego katalogu pasujące do określonego wzorca. D a te T im e G e t L a s t A c c e s s T im e ( S t r in g ś c i e ż k a ) — zwraca czas ostatniego dostępu do danego katalogu. D a te T im e G e t L a s t W r it e T im e f S t r i n g ś c i e ż k a ) — zwraca czas ostatniego zapisu do danego katalogu. S t r i ng [] G e t l _ o g i c a l D r i v e s ( ) — zwraca wszystkie dyski logiczne lokalnego komputera v o id M o v e (S t r in g z r o d l o , S t r i n g c e l ) — przenosi katalog źródłowy do katalogu docelowego wraz z podkatalogi i plikami. Katalog docelowy nie może wcześniej istnieć (w przeciwnym razie zostanie wygenerowany wyjątek klasy IO E x c e p t i on), v o id S e t L a s t A c c e s s T i m e ( S t r i n g ś c i e ż k a , D a te T im e d a t a ) — zmieniaczas ostatniego dostępu do danego katalogu. v o id S e t L a s t W r i t e T im e ( S t r i n g ś c i e ż k a , D a te T im e d a t a ) — zmienia czas ostatniego zapisu do danego katalogu.
File Klasa służy do uzyskiwania informacji o plikach. Umożliwia także ich tworzenie, edycję oraz usuwanie. Dostęp do plików przy użyciu strumieni jest omawiany w dalszej części tablicy W poniższym zestawieniu nie są ujęte metody pobierające czasy ostatniego dostępu, ostatniego zapisu do pliku, gdyż ich składnia jest identyczna ze składnią odpowiednich metod dotyczących katalogów, v o id C o p y ( S t r i n g z r o d l o , S t r i n g c e l , b oo l n a d p is y w a n ie ) — kopiuje plik pomiędzy określonymi lokalizacjami. Jeśli argument n a d p is y w a n i e ma wartość tr u e , plik znajdujący się w ścieżce c e 1 zostanie nadpisany v o id D e l e t e ( S t r i n g ś c i e ż k a ) — usuwa podany plik. v o id D e c ry p t ( S t r i n g ś c i e ż k a ) — odszyfrowuje plik zaszyfrowany przy użyciu metody E n c r y p t ( ) . v o id E n c r y p t ( S t r i n g ś c i e ż k a ) — szyfruje plik. Tylko użytkownik, który zaszyfrował plik, może go odszyfrować. Dwie powyższe metody dotyczą tylko systemów Windows NT i późniejszych, obsługujących system plików NTFS. F ile A t t r ib u t e s G e t A t t r ib u t e s ( S t r in g ś c i e ż k a ) — zwraca atrybuty dla podanego pliku, v o id M o v e (S t r in g z r o d l o , S t r i n g c e l ) — przenosi plik między podanymi ścieżkami. v o id R e p l a c e ( S t r i n g z r o d l o , S t r i n g c e l , S t r i n g k o p ia c e lu ) — przenosi plik między ścieżkami z r o d l o a c e l .Oryginalna zawartość pliku c e l zostaje zapisana wścieżce ko p i a c e l u. v o id S e t A t t r i b u t e s ( S t r i n g ś c i e ż k a , F i 1 e A t t r i b u t e s a t r y b u t y ) — ustawia określone atrybuty dla podanego pliku.
Przykład: Metoda zwraca w postaci tablicy obiektów klasy S t r i n g listę wszystkich podkatalogów i plików dla danego katalogu. Do opisu katalogu dodana jest liczba zawartych w nim plików, a do opisu pliku — określające go atrybuty. p r i v a t e S t r i n g Q m etoda ( S t r i n g s c i e zka ) ł S t r i n g Q p l i k i = D ir e c t o r y . G e t F ile s ( s c ie z k a ) ; S t r i n g Q k a t a l o g i = D ir e c t o r y . G e t D ir e c t o r ie s (s c ie z k a ); i n t i lo s e = p l i k i . L e n g th + k a t a lo g i.L e n g th ; S t r i ng [] w y n ik i = new S t r in g Q lo s c ] ; in t l ic z n ik = 0; f o r e a c h ( S t r i n g nazwa in k a t a l o g i ) { w y n i k i [1 i c z n i k ] = n a z w a + "; I l o s c p lik ó w : " + D ir e c t o r y . G e t F i l e s ( n a z w a ) .L e n g t h ; l i c z n i k += 1; 1 fo r e a c h ( S t r i n g nazwa in p l i k i ) { w y n ik i [ l i c z n i k ] = nazwa + 11; A t r y b u t y : 11 + F i l e . G e t A t t r i b u t e s (n a zw a ) . T o S t r i n g O ; l i c z n i k += 1; } r e t u r n w yni k i ; } Operacje na plikach I katalogach zostały rozdzielone ze względu na różnice w ich opisie. Powyższą metodę można nieco skrócić przez zastosowanie jednolitego opisu dla wszystkich elementów. Wywołania metod G e t F i 1 e s ( ) i G e tD i r e c t o r i es ( ) można zastąpić metodą Di r e c t o r y .G e t F i l e S y s t emEn t r i e s ( ) , a dwie konstrukcje f o r e a c h — jedną.
Strumienie
Strumienie stanowią abstrakcyjną konstrukcją obsługującą ciąg bajtów. Ogromna większość operacji polegających na wczytywaniu i zapisywaniu danych wykorzystuje strumienie. Klasą bazową dla wszystkich strumieni jest klasa S t ream. Jest to klasa abstrakcyjna Większość metod jako argumenty przyjmuje obiekty właśnie tej klasy, co gwarantuje niezwykłą elastyczność kodu (w takiej sytuacji można podać zarówno strumień obsługujący plik, jak I połączenie internetowe!). Klasy strumieni znajdują się w przestrzeni nazw S y ste m . 10.
Właściwości klasy Stream b oo l CanRead — określa, czy strumień ma możliwość czytania danych (t r u e — tak, f a l se — nie), b oo l C a n T i meout — określa, czy strumień może przerwać oczekiwanie na zapis lub odczyt w przypadku przekroczenia limitu czasu oczekiwania (t r u e — tak, f a l se — nie).
Wydawnictwo Helion ul K ościuszki 1c, 44-100 Gliw ice tel.: 32 230 98 63 e-mail: helion@ helion.pl http://helion.pl
I n fo r m a t y k a w n a jle p s z y m w y d a n iu
b oo l CanW ri t e — określa, czy strumień ma możliwość zapisywania danych (t r u e — tak, f a l se — nie), lo n g L e n g th — określa długość strumienia. 1 ong P o s it i o n — określa aktualną pozycję w strumieniu, i n t ReadT i m eout — określa maksymalny czas, przez jaki strumień będzie probowal czytać dane ze strumienia, i n t W ri t e T i meout — określa maksymalny czas, przez jaki strumień będzie próbował zapisać dane do strumienia.
S tre a m R e a d e r s t ru m ie ń = F i l e . O p e n T e x t ( s c ie z k a ); in t i = 0; S t r i n g Q b u f o r = new S t r i n g [ 5 ] ; w h ile ( i < 5 && ¡ s t r u m ie ń . E n d O fS tre a m ) { b u f o r [ i ] = s t ru m i e n . R e a d L i n e ( ) ; i += 1 ; } s t r u m ie ń .C lo s e ( ) ; S t r i n g Q w y n ik = new S t r i ng [ i ] ; A r r a y .C o p y ( b u f o r , w y n ik , i ) ; r e t u r n w y n ik ;
Metody klasy Stream v o id C l o s e ( ) — zamyka strumień i zwalnia jego zasoby, v o id F I us h ( ) — przesyła całą aktualną zawartość wewnętrznego bufora strumienia do docelowego obiektu, in t R e a d (b y te [] b u fo r, in t o f f s e t , in t i l o s c ) — zwraca ilość odczytanych danych. Są one umieszczane w danej tablicy, począwszy od elementu o indeksie o f f s e t . Maksymalna ilość odczytanych bajtów to i 1 o sc. Zwrócony wynik nie musi być równy parametrowi i l o s c . i n t R e a d B y t e ( ) — wczytuje i zwraca jeden bajt. Jeśli wystąpi błąd (dowolnego rodzaju), zwracana jest wartość - I (dlatego zwracana jest wartość typu in t j. lo n g S e e k ( lo n g o f f s e t , S e e k O r ig in p u n k t_ o d n i e s i en i a ) — przesuwa wskaźnik pozycji w strumieniu o wartość o f f s e t , uwzględniając dany p u n k t_ o d n ie s ie n ia . v o id W r i t e ( b y t e [ ] b u f o r , i n t o f f s e t , i n t i 1 o sc ) — zapisuje do strumienia i 1 o s c bajtów z danej tablicy, począwszy od elementu o indeksie o f f s e t , v o id Wri t e B y t e ( b y t e b ) — zapisuje bajt do strumienia. Jednym z najpopularniejszych przykładów użycia strumieni jest modyfikowanie plików. W poprzednim podrozdziale zostały opisane operacje na systemie plików. Klasa F i l e udostępnia wiele interesujących metod, które wykorzystują strumienie, a pozwalają na zmianę zawartości plików
File (ciąg dalszy) S tr e a m W r ite r A p p e n d T e x t ( S t r in g ś c i e ż k a ) — otwiera podany plik do dopisywania w trybie tekstowym (UTF-8) i zwraca strumień obsługujący ten plik. F ile S t r e a m C r e a t e ( S t r i n g ś c i e ż k a ) — tworzy plik znajdujący się w podanej ścieżce i zwraca strumień obsługujący ten plik w trybie binarnym. S tr e a m W r ite r C r e a t e T e x t ( S t r i n g ś c i e ż k a ) — tworzy plik znajdujący się w podanej ścieżce i zwraca strumień obsługujący ten plik w trybie tekstowym F ile S t r e a m O p e n R e a d ( S t r i n g ś c i e ż k a ) — otwiera podany plik do odczytu i zwraca strumień obsługujący ten plik w trybie binarnym. S tre a m R e a d e r 0 p e n T e x t ( S t r i n g ś c i e ż k a ) — otwiera podany plik do odczytu i zwraca strumień obsługujący ten plik w trybie tekstowym. F ile S t r e a m O p e n W rite ( S t r i n g ś c i e ż k a ) — otwiera podany plik do zapisu i zwraca strumień obsługujący ten plik w trybie binarnym. S t r i n g Q ReadA l 1 L i n e s ( S t r i n g ś c i e ż k a ) — wczytuje podany plik w trybie tekstowym i umieszcza jego zawartość w tablicy łańcuchów (|edna linijka tekstu — jeden łańcuch), po czym zamyka plik. v o id W r i t e A l l L i n e s ( S t r i n g ś c i e ż k a , S t r i n g Q z a w a r t o ś ć ) — zapisuje podaną tablicę łańcuchów do pliku w trybie tekstowym (|eden łańcuch — jedna linijka tekstu). W nagłowiach powyższych metod znajdują się odwołania do trzech klas strumieni: F i 1 e S t r e am, S t r e am Re a d e r i S tr e a m W r ite r . Pierwsza śluzy do obsługi pliku w trybie binarnym, dwie pozostałe do obsługi pliku w trybie tekstowym. Różnica między tymi typami plików polega na tym, ze plik binarny jest sekwenqą bajtów, natomiast plik tekstowy — sekwencją linii (łańcuchów przedzielanych znakami nowej linii— w systemie Windows znaki nowe| linii to znaki o kodach 13 i 10). Jeśli jest dostępny strumień F i 1 e S t ream, a istnieje konieczność użycia któregoś z pozostałych dwu strumieni, można wykorzystać ich konstruktory: S tre a m R e a d e r r e a d e r = new S tre a m R e a d e r ( o b ie k t K la s y F ile S t r e a m ) ; S t r e a m W r it e r w r i t e r = new S tr e a m W r ite r (o b i e k t K l a s y F i 1 e S t r e a m ) ; Do obsługi plików binarnych przestrzeń nazw S y s te m . 10 oferuje również klasy B i n a r y R e a d e r i B i n a ry W ri t e r . Udostępniają one szereg wariantów metody, odpowiednio: Read () i Wr i t e ( ) ; dzięki nim możliwy jest odczyt i zapis zmiennych takich typów, jak b o o l, c h a r , d e c im a l, d o u b l e, f 1 o a t, S t r i ng oraz c h a r [ ] , oraz typów liczbowych bez znaku, np. F ile S t r e a m s t r u m ie ń = F i l e . O p e n R e a d (@ "c :\ d o k u m e n t.x m l" } ; B in a r y R e a d e r c z y t n i k = new B i n a r y R e a d e r ( s t r u m ie n ) ; ch a r c = c z y t n ik .R e a d C h a r (); c z y t n ik .C lo s e ();
) W powyższych metodach najbardziej skomplikowana jest obsługa sytuacji, gdy plik nie ma określonych przez program 1024 bajtów lub 5 linii tekstu. Dzięki użyciu pomocniczych tablic b u f o r i metody A r r a y . Co p y () można jednak szybko tę sytuację rozwiązać.
XML (model DOM) w C#
Klasy i interfejsy do obsługi języka XML znajdują się w przestrzeni nazw S y ste m .X m l Podstawową klasą jest klasa Xml Docum ent. Za pomocą tej klasy można załadować dokument XML z pliku, strumienia lub przy użyciu wyspecjalizowanych klasczytników (klasa Xml R e a d e r i jej pochodne). Po utworzeniu obiektu dokumentu (konstruktor domyślny) należy wywołać jego metodę Load ( ) , aby wczytać dane: v o id L o a d ( S t r in g l o k a l i z a c j a ) — wczytuje dokument XML z podanego adresu (zarowno lokalnego, jak i sieciowego). Aby uzyskać dostęp do głównego elementu dokumentu (tzw. korzenia), trzeba wykorzystać właściwość D ocum entEl ement: Xml E le m e n t D ocum entEl e m en t— określa element korzenia w danym dokumencie XML Klasa Xml E l emen t (podobnie jak Xml Docum ent) dziedziczy po klasie Xml Node, która jest klasą bazową dla obiektów reprezentujących elementy języka XML.
XmlNode Klasa reprezentuje pojedynczy element dokumentu XML.
Właściwości klasy XmlNode Xml A t t r i b u t e C o l l e c t i o n A t t r i b u t e s — określa atrybuty elementu. Xml N o d e Li s t C h i 1 dNodes — określa wszystkie elementy należące do danego elementu. S t r i n g Name — określa nazwę elementu. Xml N odeType N odeType — określa typ elementu. S t r i ng V a l ue — określa wartość elementu.
Metody klasy XmlNode Xm lNode In s e r t A f t e r ( X m lN o d e now y, Xm lNode p u n k t O d n ie s ie n ia ) — zwracanowo dodany element XML, który jest wstawiany za elementem p u n k t O d n ie s ie n ia . Xm lNode R e m o ve C h ild (X m lN o d e e le m e n t) — zwraca usunięty element. Xm lNode R e p la c e C h ild (X m lN o d e now y, Xm lNode s t a r y ) — zwraca stary element, który uprzednio został zamieniony na nowy.
Przykład: Program wyświetla wartości elementu imię z podanego dokumentu XML:
dokumenUml