Izuzetak je neočekivani i neželjeni događaj koji se pojavio prilikom izvršavnja programa i koji ometa dalji normalan tok izvršavanja programa.
Primeri izuzetaka mogu da budu: deljenje sa nulom, pokušaj otvaranja datoteke od strane programa a da program nema dozvolu pristupa datoteci, nedostupnost mreže u toku slanja podataka, unos pogrešnog formata podatka, kod trougla da je zbir bilo koje dve stranice manji ili jednak trećoj ...
Prilikom pisanja programa treba povesti računa da se uzmu u obzir svi potencijalni izuzeci koji bi doveli do „pucanja“ programa prilikom njegovog izvršavanja ili dobijanja neželjenog rezultata.
U programskom jeziku C# svi izuzeci i sve mogućnosti upravljanja izuzecima su izvedeni iz osnovne klase Exception koja je deo System imenskog prostora. Ovu osnovnu klasu nasleđuju dve klase: ApplicationException i SystemException
SystemException
Neki sistemski izuzeci koji se najčešće javljaju su:
1) Divide By Zero exception – pokušaj deljenja sa nulom
2) IndexOutOfRangeException – pristup nepostojećem element niza
3) OutOfMemoryException – nedostatak slobodne memorije za nastavak izvršavanja programa
4) OverflowException – kada prilikom neke operacije se dobija suviše veliki ili mali rezultat koji ne može da se sačuva u određenoj promenljivoj
5) StackOverflowException – najčešće se događa prilikom rekurzije kada metoda poziva samu sebe bekonačan broj puta
6) FileNotFoundException – javlja se prilikom pokušaja otvaranja nepostojećeg fajla za čitanje
7) FormatException – javlja se u slučaju unosa podataka u lošem format (očekuje se ceo broj a unesen je string)
Takođe postoje izuzeci u radu sa bazom podataka.
ApplicationException
Iz klase ApplicationException izvode se korisnički izuzeci. Ove izuzetke kreira sam programer. Ovi izuzeci ako se jave neće dovesti do “pucanja” u radu programa već narušavaju njegovu semantiku (logičku ispravnost) tj, dovode do neželjenog rezultata u radu programa.
Primer: zbir bili koje dve stranice u trouglu mora biti veći od treće I ocene učenika moraju da budu celi brojevi u opsegu od 1 do 5.
U C# se obrada izuzetaka obavlja pomoću try-catch-finally sekvence. U try bloku nalazi se deo koda koji spada u normalni tok izvršavanja programa i u okviru kojeg može da se nađe deo koda koji sadrži izuzetak.
U catch bloku se nalazi deo koda koji se aktivira samo u slučaju kada se aktivirao određeni.
Finally blok u sebi sadrži deo koda koji se izvršava bez obzira da li se dogodio izuzetak ili ne.
Svaki try blok mora da bude praćen bar jednim (može i sa više ) catch blokova. Važan je redosled u navođenju catch blokova. Finally blok nije obavezan.
static void Main(string[] args)
{
Console.WriteLine("Program za deljenje dva cela broja");
try
{
Console.Write("Unesite deljenik:");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Unesite delilac:");
int b = Convert.ToInt32(Console.ReadLine());
int c = a / b;
Console.WriteLine("Rezultat deljenja je {0}", c);
}
catch
{
Console.WriteLine("Desila se greška");
}
finally
{
Console.ReadKey();
}
}PRIMER 1: U okviru ovog primera bilo koji izuzetak da se dogodi aktiviraće se kod u catch bloku. U ovom slučaju korisnik neće imati informaciju o tipu greške (greške mogu biti loš format podataka, deljenje sa nulom, unos prevelikog broja).
static void Main(string[] args)
{
Console.WriteLine("Program za deljenje dva cela broja");
try
{
Console.Write("Unesite deljenik:");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Unesite delilac:");
int b = Convert.ToInt32(Console.ReadLine());
int c = a / b;
Console.WriteLine("Rezultat deljenja je {0}", c);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.ReadKey();
}
}PRIMER 2: U ovom slučaju korisnik će imati informaciju o tipu greške (greške mogu biti loš format podataka, deljenje sa nulom, unos prevelikog broja).
static void Main(string[] args)
{
Console.WriteLine("Program za deljenje dva cela broja");
try
{
Console.Write("Unesite deljenik:");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Unesite delilac:");
int b = Convert.ToInt32(Console.ReadLine());
int c = a / b;
Console.WriteLine("Rezultat deljenja je {0}", c);
}
catch (DivideByZeroException)
{
Console.WriteLine("Deljenje sa nulom");
}
catch (FormatException)
{
Console.WriteLine("Očekuje se ceo broj");
}
catch (OverflowException)
{
Console.WriteLine("Uneli ste preveliki broj");
}
finally
{
Console.ReadKey();
}
}PRIMER 3: U okviru ovog primera u zavisnosti koji izuzetak da se dogodi aktiviraće se kod u odgovarajućem catch bloku.
static void Main(string[] args)
{
Console.WriteLine("Program za deljenje dva cela broja");
try
{
Console.Write("Unesite deljenik:");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Unesite delilac:");
int b = Convert.ToInt32(Console.ReadLine());
int c = a / b;
Console.WriteLine("Rezultat deljenja je {0}", c);
}
catch (DivideByZeroException e)
{
Console.WriteLine("Deljenje sa nulom");
}
catch
{
Console.WriteLine(e.Message);
}
finally
{
Console.ReadKey();
}
}PRIMER 4: Bitan je redosled navođenja catch blokova
static void Main(string[] args)
{
Console.WriteLine("Program za unos ocena ucenika");
try
{
Console.WriteLine("Unesite ocenu učenika:");
int ocena = Convert.ToInt32(Console.ReadLine());
if ((ocena < 1) || (ocena > 5))
throw new Exception("Pogrešna ocena");
// moze ApplicationException("Pogrešna ocena");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.ReadKey();
}
}Primer korisničkog izuzetka u slučaju kada uneta ocena nije iz opsega.
Domaći: napraviti kod koji proverava da li je zbir bilo koje dve stranice u trouglu uvek veći od treće stranice!