• Sterowanie przepływem
•Wyjątki
• Kolekcje
• - Tablice
• - Klasa System.Array
Sterowanie przepływem
W języku C# występują: instrukcje warunkowe if … else … , instrukcja wyboru switch oraz pętle for, while, do … while.
Ich składnia i działanie są identyczne jak w C++.
Nowa instrukcja pętli to
foreach ( typ obiekt in kolekcja_obiektów_typu) służy do przeglądania obiektów kolekcji.
Wyjątki
Ważnym elementem nowoczesnego programowania jest umiejętność korzystania z wyjątków(ang. exceptions) do sygnalizowania i obsługi błędów.
W C# wyjątkiem jest obiekt, który przenosi komunikat o błędzie z miejsca jego wystąpienia (tzn. z miejsca, z którego wyjątek jest zgłaszany) do miejsca jego obsługi.
Każdy błąd w działaniu programu powoduje utworzenie obiektu wyjątku. Zadaniem programisty jest
przewidywanie gdzie, w jakim fragmencie kodu może powstać błąd i odpowiednie jego "przechwycenie", tak aby zapobiec "załamaniu" aplikacji.
W przykładzie pokazanym na listingu 2.1 wyjątek powstaje w momencie, gdy następuje próba obliczenia
Listing 2.1
Uwaga !
Konieczne było dzielenie przez zmienną równą 0, zamiast jawnie przez 0, żeby "oszukać"
kompilator. Warto również wiedzieć, że dzielenie przez 0 jest niedopuszczalne w liczbach całkowitych, ale w przypadku liczb np. double wyjątek nie zostałby zgłoszony.
Po sekcji try można umieścić kilka sekcji catch wychwytujących poszczególne typy wyjątków.
Do zgłaszania wyjątku służy słowo kluczowe throw z następującą po nim referencją do obiektu wyjątku. Listing 2.2 zawiera przykład jego użycia.
Listing 2.2
Kolekcje
W języku C# oprócz tablic istnieją także inne struktury danych takie jak : listy, kolejki, drzewa, słownikii różne ich podtypy.
Wszystkie one, łącznie z tablicami, w C# noszą nazwę kolekcji.
Wszystkie typowe kolekcje, a także kilka dodatkowych, zostały zaimplementowane na platformie .NET i są dostępne w przestrzeni nazw System.Collections.
Wyjątkiem jest "zwykła" tablica, której definicja znajduje się w przestrzeni System.
W wersji 2.0 platformy .NET dodano dwie nowe przestrzenie nazw:
System.Collections.Generic oraz
System.Collections.Specialized
Pierwsza zawiera kolekcje zdefiniowane za pomocą tzw. klas parametryzowanych, (nowość od wersji 2.0 języka), druga — ich wyspecjalizowane wersje.
"Zwykłe" tablice
Definicja tablicy w dowolnym języku programowania jest zawsze taka sama:
"Tablica zbiór elementów tego samego typu"
W C# tablice zaimplementowano w taki sposób, aby niemożliwe było popełnianie częstego błędu, w którym dochodzi do odczytu lub zapisu danych "poza"
zadeklarowanym rozmiarem tablicy.
W C# indeksy są kontrolowane przez klasę implementującą
System.Array- tablica jest obiektem tej klasy.
Zasady tworzenia tablic w C# są prawie identyczne jak w przypadku dynamicznie
tworzonych tablic w C++. Można zadeklarować tablicę, co oznacza utworzenie referencji
do tablicy, zdefiniować ją, czyli zarezerwować pamięć, a następnie zainicjować, czyli
zapełnić wartościami.
Przykład poprawnej składni deklaracji referencji do tablicy z elementami typu int:
int[] i;
Przykład utworzenia obiektu takiej tablicy:
i = new int[5];
w obszarze sterty zarezerwowano w ten sposób miejsce na 5 elementów tablicy o elementach typu int.
Deklarację referencji na tablicę można połączyć z utworzeniem obiektu tej tablicy i inicjalizacją jej elementów domyślnymi wartościami 0:
int[] i = new int[5];
Tablice w C# są typami referencyjnymi tworzonymi w obszarze sterty.
W przypadku utworzenia obiektu tablicy (instancji klasySystem.Array) jest ona
automatycznie inicjowana wartościami domyślnymi dla danego typu (zob. tabela 2.1), czyli w przypadku typuint — zerami.
Można także samodzielnie zainicjować elementy tablicy:
int[] n=new int[3] {1,2,4};
W przypadku tablicy zawierającej typy referencyjne domyślne wartości elementów tablicy to null.
Konieczna jest wobec tego jawna inicjacja elementów przez wywoływanie operatoranew dla każdego elementu tablicy i utworzenie odpowiedniej grupy obiektów.
Rozważmy następujące polecenia:
(1) Button[] b;
Label1.Text = "" + b[0].Text;
(2)Button[] b = new Button[3];
Labell.Text = "" + b[0].Text;
(3)Button[]b = new Button[3] {new Button(),new Button(), new Button()};
Labell.Text = "" + b[0].Text;
Polecenia z grupy (1) w ogóle się nie skompilują, ponieważ w drugim wierszu próbujemy odwołać się do zmiennej b (referencji do tablicy), która nie została zainicjowana.
Polecenia (2) skompilują się i program można uruchomić, ale podczas działania zostanie zgłoszony wyjątek NullReferenceException.
Dlaczego?
Tablica b jest co prawda utworzona (obiekt tablicy powstał) i zainicjowana, ale domyślne wartości referencji, a to one są tu elementami przechowywanymi w tablicy, to null(są nieokreślone – nie ma ich).
Nie powstał oczywiście żaden obiekt klasy Button, więc nie mogą one przechowywać żadnych adresów, a co za tym idzie, próba odczytania właściwości Textnieistniejących obiektów musi skończyć się błędem.
Dopiero w poleceniach (3) tablica zostaje zapełniona referencjami zawierającymi adresy do istniejących obiektów i na komponencie Label1zobaczymy pustą etykietę pierwszego przycisku.
Tabela 2.1. Metody i właściwości klasy System.Array
Metoda lub właściwość Działanie
BinarySearch() Przeciążona publiczna metoda statyczna do wyszukiwania elementów w jednowymiarowych posortowanych tablicach
Clear() Publiczna metoda statyczna, która przypisuje elementom tablicy wartości 0 lub referencje null
Copy() Przeciążona publiczna metod statyczna, która kopiuje fragment tablicy do innej tablicy CreateInstance() Przeciążona publiczna metoda statyczna, która tworzy nowy egzemplarz tablicy IndexOf() Przeciążona publiczna metoda statyczna, która zwraca indeks (pozycję) pierwszego
wystąpienia danej wartości w tablicy jednowymiarowej
LastIndexOf() Jw.. – zwraca pozycję ostatniego wystąpienia danej wartości
Reverse() Przeciążona publiczna metoda statyczna, która "odwraca" kolejność elementów w tablicy jednowymiarowej
Sort() Przeciążona publiczna metoda statyczna do sortowania wartości w tablicy jednowymiarowej IsFixedSize Wymagana właściwość, w przypadku tablic zawsze zwraca wartość true
IsReadOnly Publiczna właściwość, której wartość logiczna określa, czy dana tablica służy tylko do odczytu Length Publiczna właściwość zwracająca długość tablicy
Rank Publiczna właściwość zwracająca liczbę wymiarów tablicy
GetLength() Publiczna właściwość, która zwraca długość danego wymiaru tablicy
GetLowerBound() Publiczna metoda, która zwraca dolny indeks określonego wymiaru tablicy GetUpperBound() Publiczna metoda, która zwraca górny indeks określonego wymiaru tablicy
Initialize() Inicjuje wszystkie wartości typu skalarnego, w ten sposób że dla każdego elementu konstruktor domyślny. W przypadku typów referencyjnych wszystkie elementy tablicy ustawia na null
SetValue() Przeciążona metoda publiczna, która przypisuje zakresowi elementów określoną wartość
Przykład użycia i działania niektórych metod i właściwości w klasie System.Array ilustruje listing 2.3.
Listing 2.3
Klasa System.Array obsługuje oprócz tablic wielowymiarowych tzw. prostokątnych (cechą charakterystyczną jest taka sama liczba elementów każdego "wymiaru") również tablice
"nieregularne".
Są to tablice, których elementami są tablice – czyli tablice tablic.
Każda taka tablica może mieć inną liczbę elementów. Deklaracja takiej tablicy ma postać:
typ [][]...
Liczba par nawiasów prostokątnych określa wymiar tablicy.