try…catch
Transkrypt
try…catch
Temat: Klasa Exception. Generowanie, chwytanie i obsługa wyj tków. Instrukcja „try…catch” i „try finally”. Strumienie plikowe. Wła ciwo ci. Przestrzenie nazw. Kolekcja ArrayList. 1. Klasa Exception Rodzaje bł dów w programach : • bł dy kompilacji (bł dy składniowe) • bł dy logiczne • bł dy wykonania Wyst pienie bł du wykonania mo e skutkowa zaprzestaniem działania programu, systemu, w którym ten pogram jest uruchomiony albo urz dzenia z którym współpracuje. Dlatego te programista powinien : • przewidzie wszystkie mo liwo ci wyst pienia bł dów wykonania (wyj tków programu), • obsługi sytuacji wyst pienia bł dów wykonania (obsługi wyj tków), Bł dy wykonania mo e generowa sam program, jego u ytkownik, system operacyjny w którym program pracuje czy urz dzenia z którym program współpracuje. Generowanie, chwytanie i obsług wyj tków w programach napisanych w j zyku C# mo na realizowa wykorzystuj c specjaln hierarchi klas. Przykład 1 Przykłady wyj tków int[] arr = new int[20]; for (int i = 1; i <= 20; i++) arr[i] = i; Wykonanie powy szego kodu generuje wyj tek klasy IndexOutOfRangeException – indeks wykracza poza granice (tablicy) string s = "abc"; int n = int.Parse(s); Wykonanie powy szego kodu generuje wyj tek klasy FormatException – nieprawidłowy format ci gu wej ciowego. string s = null; Console.WriteLine("Pierwszy znak =" + s[0]); Wykonanie powy szego kodu generuje wyj tek klasy NullReferenceException odwołanie do obiektu nie zostało ustawione na wyst pienie obiektu. • Gdy system stwierdzi bł d, tworzona jest instancja (obiekt) klasy, która opisuje dany bł d. • Nazwa klasy zawiera słowo Exception i przedrostek specyfikuj cy wyj tek, np : NullReferenceException. Klasa wyj tku jest zawsze potomna w stosunku do klasy Exception. • Do „chwytanie” („łapania”) i obsługi wyj tków słu y specjalna konstrukcja j zykowa try … catch. • Do „rzucania” (generowania) wyj tku słu y specjalny rozkaz throw. 2. Generowanie, chwytanie i obsługa wyj tków. Instrukcja “try-catch” i “try-finally” Przykład 2 Chwytanie i obsługa wyj tku static void Main(string[] args) { int[] A = new int[20]; int i, k; i = 21; k = 3; try { int temp = A[i] / k;//bł d wykonania!!! A[i + 1] = A[i] / k; A[i + 1] = int.Parse("10" + temp); } catch (System.IndexOutOfRangeException e) { Console.WriteLine("Bład:{0}",e.ToString()); } } Komunikat na ekranie: Bł d: System.IndexOutOfRangeException: Indeks wykraczał poza granice tablicy w wyk8.Program.Main(String[] args) w H:\PPO\wyk8\ Program.cs:wiersz 16 Przykład 3 Chwytanie i obsługa wyj tków static void Main(string[] args) { int [] A=new int [20]; int i,k; for (i = 0; i < 20; i++) A[i] = i + 1; try { Console.Write("Podaj liczb :"); k = int.Parse(Console.ReadLine()); i = 21; int temp = A[i] / k; Console.WriteLine("Wszystko w porz dku"); } catch (System.IndexOutOfRangeException e) { Console.WriteLine("Bł dny indeks !!!"); } catch (System.DivideByZeroException) { Console.WriteLine("Dzielenie przez zero !!!"); } catch (System.FormatException) { Console.WriteLine("Bł d konwersji napisu na liczb całkowita !!!"); } } Przykład 4 Uogólniona obsługa wyj tków static void Main() { int[] A = new int[20]; int i, k; for (i = 0; i < 20; i++) A[i] = i + 1; try { Console.Write("Podaj liczb :"); k=int.Parse(Console.ReadLine()); i = 21; int temp = A[i] / k; } catch (System.Exception e) { Console.WriteLine("Jaki bł d !!!: {0}", e.ToString()); } } Przykład 5 Uogólniona obsługa wyj tków static void Main() { int[] A = new int[20]; int i, k; for (i = 0; i < 20; i++) A[i] = i + 1; try { Console.Write("Podaj liczb :"); k=int.Parse(Console.ReadLine()); i = 21; int temp = A[i] / k; } catch { Console.WriteLine("Jaki bł d !!!"); } } • W ka dym z bloków catch typ wyj tku musi by inny. • Dla jednego bloku try mo na u y tylko jednego bloku catch, w którym typ wyj tku nie jest okre lony. • Blok catch z typem wyj tku klasy potomnej musi si pojawi przed blokiem catch wyj tku klasy bazowej. catch (Exception e) {…} catch (OutOfMemoryException e) {…} // bł d !!! Przykład 6 Generowanie wyj tku class ZlyFormatCzasu: Exception { public ZlyFormatCzasu(string Message): base(Message) { } // dana Message w klasie Exception jest prywatna // i ustawia j konstruktor tej klasy // base(Message) to wywołanie tego konstruktora } class Program { static void Main() { bool blad=false; do { try { blad=false; Console.Write("Podaj czas hh mm:"); string napis=Console.ReadLine(); string [] napisy=napis.Split(); // Split - metoda dziel ca lini napisu na // cz wg spacji int hh=int.Parse(napisy[0]); int mm=int.Parse(napisy[1]); if (hh<0 || hh>24 || mm<0 || mm>60) { blad=true; throw new ZlyFormatCzasu("Zle podany czas !!!"); } Console.WriteLine("{0}:{1}\n",napisy[0],napisy[1]); } catch (ZlyFormatCzasu e) { Console.WriteLine(e.Message); } } while (blad); } } • Instrukcje try-catch i try-finally mo na zagnie d a . • Je eli wyj tek jest rzucany w bloku finally, to jest de facto przerzucany do nast pnego bloku catch. Przykład 7 Blok finally. Przerzucanie wyj tku. class ExampleException : Exception { public ExampleException(string Message) : base(Message) { } } class Program { static void Main() { int i,j=-6; try { try { Console.Write("Podaj liczb :"); i =int.Parse(Console.ReadLine()); } catch { Console.WriteLine("Jaki bł d !!!"); } finally { int k = j++; if (k < 0) throw new ExampleException("Liczba ujemna "); } } catch (ExampleException e) { Console.WriteLine("Bł d !!! : {0}", e.Message); } } } 3. Strumienie plikowe Przykład 8 Tworzenie pliku do zapisu z obsług wyj tku using System.IO; // przestrze zawieraj ca klasy //StreamWriter i StreamReader static void Main() { StreamWriter outFile = null; string outFileName = "mydata.txt"; try { outFile = new StreamWriter(outFileName); // tutaj mo e realizowa operacje zapisu do pliku } catch (Exception e) { Console.WriteLine("Bł d tworzenia pliku {0}, powód:{1}", outFileName, e.ToString()); } } Przykład 9 Tworzenie pliku do zapisu z obsług wyj tku static void Main() { StreamWriter outFile = null; try { outFile = new StreamWriter(„c:\\temp\\dane.dat”); // tutaj mo e realizowa operacje zapisu do pliku } catch (Exception e) { Console.WriteLine("Bł d tworzenia pliku dane.dat,powód:{0}", e.ToString()); } } • Metody klasy StreamWriter, które realizuj zapis do pliku to metody: Write i WriteLine Przykład 10 Zapis do pliku static void Main() { StreamWriter outFile=null; string outFileName="c:\\temp\\mydata.txt"; try { outFile=new StreamWriter(outFileName); } catch (Exception e) { Console.WriteLine("Bł d tworzenia pliku {0},powód:{1}",outFileName,e.ToString()); } int i=2,j=3; double f=4.0; outFile.WriteLine("To jest pierwsza linia pliku"); outFile.Write("i = {0} ",i); outFile.WriteLine("j ={0},f*2 = {1:F2}",j,f*2.0); outFile.Close(); //zamkni cie strumienia plikowego } • Metody klasy StreamReader, które realizuj odczyt z pliku to metody: Read i ReadLine oraz ReadToEnd. • Metoda Read czyta jeden znak z pliku. • Metoda ReadLine czyta lini pliku. • Metoda ReadToEnd czyta cały plik. Przykład 11 Odczyt z pliku static void Main() { StreamReader inFile=null; string inFileName="c:\\temp\\mydata.txt"; try { inFile=new StreamReader(inFileName); } catch (Exception e) { Console.WriteLine("Bł d tworzenia pliku {0}, powód:{1}",inFileName,e.ToString()); } string s=inFile.ReadLine(); Console.WriteLine(s); char k; while (!inFile.EndOfStream) { k=(char)inFile.Read(); Console.Write(k); } inFile.Close(); } Przykład 12 Odczyt z pliku do tablicy ……… string dane=inFile.ReadToEnd(); string [] nums=dane.Split(' ','\n','\r'); int [,] T=new int [3,3]; int ix=0; for (int i=0;i<3;i++) { for (int j=0;j<3;j++) { while (nums[ix]=="") ix++; T[i,j]=int.Parse(nums[ix++]); } } inFile.Close(); • Metoda statyczna Exists klasy File zwraca warto true, gdy plik przygotowany do odczytu istnieje w podanej parametrem cie ce: bool File.Exists( cie ka); • Metoda statyczna Copy klasy File kopiuje plik: File.Copy( cie ka_pliku_zródłowego, Je eli parametr nadpisz ma warto cie ka_kopii, nadpisz); true, to kopia pliku nadpisuje plik o tej samej cie ce • Metoda statyczna Delete klasy File kasuje plik z podanej parametrem cie ki File.Delete( cie ka) 4. Wła ciwo ci • Wła ciwo ci upraszczaj realizacj dost pu do danych w sensie operacji read/write Przykład 13 Klasa bez wła ciwo ci class Klasa { int v; public void SetValue(int v) { if (v < 10) this.v = v; else v = 10; } public int GetValue() { return v; } class Program { static void Main() { Klasa o = new Klasa(); o.SetValue(o.GetValue()+1);//skomplikowane! o.Value++; // proste i wygodne } } • Własciwo jest składnikiem klasy, który realizuje dost p do danych składowych obiektu. • Akcesory to metody dost powe, okre laj ce sposób odczytu warto ci danej z obiektu (akcesor get) albo zapisu warto ci danej w obiekcie (akcesor set). • Akcesory s metodami bez parametrów. Przykład 14 Klasa z wła ciwo ci class Klasa { int v; public int Value { set { if (value < 10) v = value; else v = 10; } get { return v; } } } class Program { static void Main() { Klasa o = new Klasa(); o.Value++; } } Przykład 14 Wła ciwo typu read-only class BankAccount { private double balance; public double Balance { get { return balance; } } } class Program { static void Main() { BankAccount acc = new BankAccount(); acc.Balance = 1000000; // bł d !!! Console.ReadLine(); } } 5. Przestrzenie nazw • Klasy w programie napisanym w j zyku C# pogrupowane s w rozł cznych przestrzeniach nazw (tzw. namespace'ach). • Dost p do klas umieszczonych w okre lonej przestrzeni nazw mo liwy jest dzi ki konstrukcji: NazwaPrzestrzeniKlas.NazwaFunkcji(…); System.Console.WriteLine(...); • Mo na zadeklarowa na pocz tku programu ch dost pu do okre lonej przestrzeni nazw using NazwaPrzestrzeniKlas; using System; Dzi ki temu do funkcji z tej przestrzeni nazw mo na odwoływa si bez poprzedzania ich nazw nazw przestrzeni nazw. • Podział programu na ró ne przestrzenie nazw zwykle wynika z logicznego podziału programu na moduły. Nie wnikaj c w struktur , moduł zawiera opis klas, przy czym moduł wykonywalny (*.exe) ró ni sie od modułu-biblioteki (*.dll) tylko tym, e w jednej z klas zawiera kod startowy (tu: funkcje Main()). Przykład 15 Przestrze nazw namespace ExampleModule { public class ExampleClass { public int Metoda() { return 17; } } } Program wykorzystuj cy przestrze nazw ExampleModule using ExampleModule; namespace Example { public class CMain { public static void Main() { ExampleClass e = new ExampleClass(); int x=e.Metoda(); } } } • Moduł główny i biblioteka mog by kompilowane niezale nie. Prawidłowe wykonanie kodu modułu mo liwe jest tylko wtedy, kiedy biblioteka b dzie dost pna dla rodowiska uruchomieniowego w czasie wykonania programu, czyli na przykład znajdzie sie w tym samym folderze co moduł główny. • Je eli nie zostanie zastosowany aden modyfikator dost pu, to wszystkie typy zadeklarowane w danej przestrzeni b d typu internal, co oznacza, e typ taki jest dost pny tylko w innych typach tej samej przestrzeni. Aby okre lony typ był dost pny w innej przestrzeni, nale y wpisa przed jego deklaracj słowo public. Inne modyfikatory nie s dozwolone. 6. Kolekcja ArrayList • Najwa niejsze wła ciwo ci i metody klasy ArrayList: wła ciwo ci: Capacity - zwraca pojemno kolekcji, Count – zwraca liczb elementów kolekcji metody: int IndexOf(v) - zwraca indeks pierwszego wyst pienia poszukiwanego elementu v albo –1, gdy elementu v nie ma w kolekcji, stosuj c wyszukiwanie liniowe, int LastIndexOf(v) - zwraca indeks ostatniego wyst pienia poszukiwanego elementu v albo –1, gdy elementu v nie ma w kolekcji, stosuj c wyszukiwanie liniowe, bool Contains(v) – zwraca true, gdy element v wyst puje w kolekcji, void Clear(first, num) – usuwa num elementów od indeksu first void Clear() – usuwa wszystkie elementy, void RemoveAt(i) – usuwa element z indeksu i void Sort() – sortuje elementy kolekcji. Metoda mo e by wywołana pod warunkiem, e klasy wszystkich obiektów znajduj cych sie w kolekcji maj zaimplementowany interfejs System.Colletions.IComparer. Do interfejsu tego nale y metoda Compare(object,object), która definiuje sposób porównywania obiektów. Inne kolekcje dost pne z przestrzeni System.Collections: - StringList, - SortedList, - BitArray, - HashTable, - Queue, - Stack • Do przegl dania kolekcji wygodniejsz p tl od p tli typu for jest p tla typ foreach. Posta ogólna: foreach (typ_elementów_kolekcji zmienna_iteruj ca in kolekcja) { // instrukcje wykonywane w p tli } Sposób realizacji: Zmienna iteruj ca przyjmuje warto ci kolejnych elementów kolekcji, na których mog by wykonywane instrukcje zawarte w bloku p tli. Przykład 16 using System.Collections; class Element1 { string napis; public Element1(string napis) { this.napis = napis; } public string Napis { get { return napis; } } } class Element2 { int liczba; public Element2(int liczba) { this.liczba = liczba; } public int Liczba { get { return liczba; } } } class Program { static void Main() { ArrayList Lista = new ArrayList(100); Element1 A1 = new Element1("Ula"); Element1 B1 = new Element1("Ewa"); Element2 A2 = new Element2(1); Element2 B2 = new Element2(2); Lista.Add(A1); Lista.Add(A2); Lista.Add(B1); Lista.Add(B2); int s = 0; foreach (object z in Lista) { if (z is Element2) s += ((Element2)z).Liczba; } Console.WriteLine("Suma wynosi: {0}:", s); foreach (object z in Lista) { if (z is Element1) Console.WriteLine(((Element1)z).Napis); } } }