Sunteți pe pagina 1din 19

Tratarea excepiilor n C#

Cuprins

Introducere....................................................................................................3
1. Clasa Exception.......................................................................................4
2. Blocurile Try Catch Finally...............................................................8
3. Crearea propriilor excepii.....................................................................14
Concluzii.....................................................................................................17
Bibliografie.................................................................................................18

Introducere
C#, la fel ca alte limbaje de programare permite tratarea erorilor i a situa iilor deosebite prin
excepii. Adic gestiunea situaiilor neprevzute, care apar n momentul execuiei unui program este
implementat prin intermediul excepiilor.
Prin excepie se nelege un obiect care ncapsuleaz informaii despre situaii anormale n
funcionarea unui program. Excepia se folosete pentru a semnala contextul n care apare o situaie
special.
Un lucru foarte important la crearea unei aplicaii este ca aceasta s nu conin erori, precum i
ca produsul final s conin mesaje de eroare adresate utilizatorului n cazul n care sunt introduse
date eronate.
Apariia unei erori poate fi cauzat de mai muli factori, pentru a afla cauza precis a acesteia,
se utilizeaz excepiile.
Excepiile permit gestiunea erorilor de sistem i a erorilor definite de programator.
O excepie reprezint o eroare care intervine la momentul execuiei unu program. n C#
excepiie se pot trata ntr-o manier controlat, acest lucru msemnnd faptul c programatorul nu
trebuie s mai verifice manual dac o operaiune se execut sau nu cu succes.
C# definete excepii standard pentru tipuri de erori obinuite dintr-un program (mpr irea la
zero, memorie insuficient, depirea capacitii unui vector).
Se disting doua clase prin reprezentarea a doua categorii generale de excepii: exceptii
generate de motorul de execuie SystemException si excepii generate de programele de aplicatie
ApplicationException. Ele nu adaug membri noi la clasa de baza, ci doar definesc rdcile celor
doua ierarhii de clase care reprezint excepii. Programatorul ii poate defini propriile clase care
reprezinta exceptii prin derivarea clasei ApplicationException.
Clasa SystemException i derivate ale acesteia, servesc la tratarea adecvat i diversificat a
excepiilor.

1. Clasa Exception
Tratarea excepiilor ofer un mecanism pentru semnalarea condiiilor excepionale care pot
aprea n timpul execuiei programului.
Excepiile sunt de fapt obiecte derivate din System.Exception care conine informaii despre
tipul erorii i locul unde a aprut. Se pot folosi excep ii predefinite, dar se pot crea i excep ii noi
prin definirea unei clase derivate din System.Exception. Exist o ierarhie de excepii care se pot
folosi, sau se pot crea propriile tipuri excepii.
Constructorii clasei Exception:

Exception() - iniializeaz o nou instan a clasei Exception;


Exception(SerializationInfo,StreamingContext) - iniializeaz o nou instan a clasei

Exception cu datele serializate;


Exception(String) - iniializeaz o nou instan a clasei Exception cu un mesaj de

eroare specificat;
Exception(String,Exception) - iniializeaz o nou instan a clasei Exception cu un
mesaj de eroare specificat i o referire la excepia interioar, care este cauza exceptiei,
preia un obiect de tip Exception (sau de tip clas derivat) care va fi ncapsulat n
instana curent, astfel, o excepie poate s conin n interiorul sau o instan a altei
excepii.

Proprietile clasei Exception:

public virtual IDictionary Data { get; } - o colectie de valori care furnizeaza informaii
suplimentare despre excepie, definite de utilizator. Un obiect ce implementeaz
interfaa System.Collections.IDictionary i conine o colecie de perechi chei / valoare

definite de utilizator. Valoarea implicit este o colecie goal.


public virtual string HelpLink {get; set;} obine sau seteaz un link ctre un fiier

help asociat acestei excepii; poate fi de asemenea o adres WEB (URL).


public int HResult { get; protected set; } - returneaz sau seteaz o valoare numeric

codificat, care este atribuit unei anumite excepii.


public Exception InnerException {get;} - returneaz excepia care este ncorporat n
excepia curent. Proprietatea InnerException returneaz aceeai valoare ce a fost
trecut n constructorul Exception (String, Exception), sau valoarea nul daca valoarea

excepiei interioroare nu a fost furnizat constructorului.


public virtual string Message {get;} obine un mesaj care descrie excepia curent.
4

public virtual string Source {get; set;} - obine sau seteaz numele aplicaiei sau al

obiectului care a cauzat eroarea.


public virtual string StackTrace {get;} obine o reprezentare string a apelurilor de

metode care au dus la apariia acestei excepii.


public MethodBase TargetSite {get;} obine metoda care a aruncat excepia curent.
MethodBase este o clas care pune la dispoziie informaii despre metodele i
constructorii unei clase.

Metodele clasei Exception:

Equals(Object) - Determina daca obiectul specificat este egal cu obiectul curent,


sintaxa: public virtual bool Equals(object obj). Va avea valoarea true daca obiectul

specificat este egal cu obiectul curent, n caz contrar, false.


Finalize() - metoda de finalizare este utilizat pentru a efectua operaiuni de curare pe
resurse negestionate, deinute de obiectul curent, nainte ca obiectul sa fie distrus.
Metoda este protejat i prin urmare este accesibil doar prin aceasta clas sau printr-o

clas derivat, sintaxa: protected virtual void Finalize().


GetBaseException() - n cazul n care proprietatea InnerException a excepiei curente
este o referin nula (Nimic n Visual Basic), acest proprietate ntoarce excep ia

curent, sintaxa: public virtual Exception GetBaseException().


GetHashCode() - un cod hash este o valoare numeric care este folosit pentru a
introduce i a identifica un obiect ntr-o colecie pe baz de hash cum ar fi clasa
Hashtable, sau un tip derivat din clasa DictionaryBase. Metoda GetHashCode prevede
acest cod hash pentru algoritmi care au nevoie de controale rapide de egalitate obiect,

sintaxa: public virtual int GetHashCode().


GetObjectData(SerializationInfo,StreamingContext) GetObjectData - stabilete un
SerializationInfo cu toate datele obiectului excepiei, vizate pentru serializare, sintaxa:
[SecurityCriticalAttribute] public virtual void GetObjectData(SerializationInfo info,

StreamingContext context).
GetType()- obine tipul de rulare a instanei curente, sintaxa: public Type GetType().
MemberwiseClone() - creeaz o copie superficial a obiectului curent, sintaxa:

protected object MemberwiseClone().


ToString() - Creeaz i returneaz o reprezentare string a excepiei curente , sintaxa:
public override string ToString().

Lansarea unei excepii se face folosind instruciunea throw.

Cnd este necesar de a se arunca, lansa o excepie, este posibilitatea de a se utiliza unul sau
mai mlte tipuri de excepii existente in .Net.
Tipuri de excepii si condiiile cnd pot fi lansate:
ArgumentException - exceptia este lansat cnd unul din argumentele transmis metodei
este invalid, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class ArgumentException : SystemException, ISerializable

ArgumentNullException - argumentul transmis este nul, dar nu trebuie sa fie nul,


sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class ArgumentNullException : ArgumentException

ArgumentOutOfRangeException - Un aurgument este n afara intervalului valorilor


valide, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class ArgumentOutOfRangeException : ArgumentException, Iserializable

DirectoryNotFoundException - Excepia care este lansat, atunci cnd o parte a unui


fiier sau director nu poate fi gsit, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class DirectoryNotFoundException : IOException

DivideByZeroException - Excepia este lansat atunci cnd exist o ncercare de a


diviza o valoare la zero (Exemplul 3), sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class DivideByZeroException : ArithmeticException

DriveNotFoundException - Excepia este lansat, atunci cnd se ncearc s se


acceseze o unitate care nu este disponibil, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class DriveNotFoundException : IOException

FileNotFoundException - Excepia este lansat atunci cnd se ncerc de a accesa un


fiier care nu exista, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class FileNotFoundException : IOException
6

FormatException - Excepia este lansat, atunci cnd formatul unui argument este
invalid (Exemplul 1), sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class FormatException : SystemException

IndexOutOfRangeException - Excepia este lansat, atunci cnd se ncearc de a se


accesa un element dintr-o serie sau colecie, cu un indice invalid (Exemplul 4), sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public sealed class IndexOutOfRangeException : SystemException

InvalidOperationException - Excepia este lansata, atunci cnd se apeleaz o metod


ce nu este valabil pentru starea curent a obiectului, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class InvalidOperationException : SystemException

KeyNotFoundException - Excepia este lansat, atunci cnd cheia specificat pentru


accesarea unui element dintr-o colecie, nu poate fi gsit, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class KeyNotFoundException : SystemException, ISerializable

NotImplementedException - Excepia este lansat, atunci cnd o metod sau o


operaiune solicitat nu este implementat, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class NotImplementedException : SystemException

NotSupportedException - Excepia este lansat, atunci cnd o metod sau o


operaiune nu este acceptat, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class NotSupportedException : SystemException

ObjectDisposedException - Excepia este lansat, atunci cnd o operaiune este


realizat pe un obiect care a fost eliminat, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class ObjectDisposedException : InvalidOperationException

OverflowException - Excepia este lansat, atunci cnd o opera ie aritmetic produce


un rezultat care este n afara intervalului tipului de date returnat de opera ie (Exemplul
1), sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
7

public class OverflowException : ArithmeticException

PathTooLongException - Excepia este lansat, atunci cnd un fiier este mai mare
dect lungimea maxim definit de sistem, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class PathTooLongException : IOException

PlatformNotSupportedException - Excepia este lansat, atunci cnd, operaiunea


dorit nu este acceptat pe platforma actual, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class PlatformNotSupportedException : NotSupportedException

RankException - Excepia este lansat, atunci cnd un tablou cu un numr greit de


dimensiuni este trecut la o metod, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class RankException : SystemException

TimeoutException - Excepia este lansat, atunci cnd timpul alocat pentru un proces
sau o operaiune a expirat, sintaxa:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class TimeoutException : SystemException

UriFormatException - Excepia este lansat, atunci cnd este detectat un identificator


uniform de resurse invalid (URI), sintaxa:
[SerializableAttribute]
public class UriFormatException : FormatException, ISerializable

2. Blocurile Try Catch Finally


Cuvintele cheie rezervate n C# pentru tratarea excepiilor sunt try, catch, finally, throw.
Acestea reprezint un sistem unitar, deoarece utilizarea unuia dintre ele, implic i utilizarea altuia.
Blocul try conine instruciunele care trebuie verificate pentru apariia erorilor. Dac pe
parcursul execuei aestora apare o excepie aceasta este aruncat, lansat (thrown).
Prin intermediul blocului catch programul poate prinde excepia i o poate trata.
Instruciunile din catch se execut doar dac apare o excepie. Pot exista mai multe instruc iuni
catch asociate unui try (Exemplul 1).
Exemplu 1: Excepii care apar la convertirea unui string la ntreg.
Codul programului:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int n = 0;
string s;
Console.Write("n = ");
s = Console.ReadLine();
try
{
n = int.Parse(s);
}
catch (OverflowException)
{
Console.WriteLine("Numarul citit este prea mare");
}
catch (FormatException)
{
Console.WriteLine("Datele citite nu sunt numerice");
}
finally
{
Console.WriteLine(n);
}
Console.ReadLine();
}
}
9

Rezultatele execuiei programului n cazul n care conversia a avut loc (Img. 1):

Img. 1 Conversia unui string la ntreg

Cazul n care numarul convertit este prea mare i nu poate fi memorat ntr-un ntreg, este trat
prin intermediul excepiei OverflowException (Img. 2):

Img. 2 Conversia unui numr prea mare

Cazul n care elementul convertit nu este numeric, este trat prin intermediul excep iei
FormatException (Img. 3):

Img. 3 Conversia unui element care nu este numeric

n cazul n care conversia nu a avut loc, se va afia valoarea 0 (zero).

10

CLR1 va cuta instruciunea catch care va trata excepia. Daca nu este gasit nici un catch,
atunci CLR va afisa un mesaj cum ca excepia nu este tratat, unhandled exception message, apoi va
opri execuia programului (Exemplul 2).
Exemplul 2: Lipsesc blocurile catch.
static void Main(string[] args)
{
int n = 0;
string s;
Console.Write("n = ");
s = Console.ReadLine();
try
{
n = int.Parse(s);
}
finally
{
Console.WriteLine(n);
}
Console.ReadLine();
}

Rezultatele execuiei programului:

Img. 4 Introducerea elementului ce urmeaz a fi convertit

1 Common Language Runtime (CLR) este un mediu de executie reuit, care este parte a cadrului

Microsoft .Net. CLR gestioneaz executarea programelor scrise n diferite limbaje suportate.
11

Img. 5 Unhandled exception message

Excepiile necesit tratare diferit n funie de tipul lor. Este important de a se oferi mai multe
blocuri catch, coninnd cod de tratare pentru fiecare tip de eroare n parte
Instruciunile dintr-un bloc finally se execut intotdeauna, chiar dac o excepie este prinsa sau
nu. Acest bloc este folosit pentru a curaa resursele folosite ntr-un bloc try si pentru a asigura
executarea unor instruciuni de cod indiferent de modul n care se iese din blocul precedent de try.
Blocul try nu poate fi prezent fr blocul catch sau finally i nici invers. Blocul finally este
obional.
try
{
//in acest bloc exceptia este "aruncata"
}
catch
{
//in acest bloc exceptia este "prinsa"
}
finally
{
//codul de curatare, optional
}

Astfel, succesiunea execuiei este urmtoarea:


se execut instruciunile din blocul try pn la apariia unei exepii, n cazul n care nu se
declanaz nici o exepie se execut ntregul bloc;
dac a aprut o exepie se compar tipul exepiei cu tipurile din lista de catch i se execut
blocul de instruciuni corespunztor pentru tratarea exepiei, comparaia se face n ordinea n care
apar blocurile catch, dup execuia unui bloc catch nu se continu cautarea n celelalte blocuri catch,
deci excepiile mai generale trebuie puse dup excepiile particulare;
se execut instruciunile din blocul finally (indiferent dac a aprut sau nu o exepie i
indiferent dac aceasta a fost tratat sau nu);
12

daca nu a aprut nici o exepie sau dac excepia a fost tratat printr-un bloc catch execuia
continu cu instruciunile de dup blocul finally, altfel excepia este propagat n apelator.
Blocurile try catch finally pot fi incluse n alte blocuri try.
Exemplul 3: Determinarea restului mpririi a dou numere
Condul programului:
static void Main(string[] args)
{
int a, b, r=0;
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
Console.Write("Restul impartirii lui {0} la {1} : ", a, b);
try
{
r = a % b;
}
catch (DivideByZeroException)
{
Console.WriteLine("Eroare. Impartire prin zero!");
}
finally
{
Console.WriteLine(r);
}
Console.ReadLine();
}

Rezultatele execuiei programului:

Img. 6 Restul mpririi a dou numere

n exemplul dat, se observ c atunci cnd mpritorul este 0 (zero), atunci este aruncat o
exepie: DivideByZeroException.

Exemplul 4: Depirea dimensiunilor unui vector


Codul programului:
13

static void Main(string[] args)


{
int[] t = { 8,7,5,6,4,1,7};
int i, s = 0;
try
{
for (i = 0; i < 8; i++)
s += t[i];
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Acces la componente din afara tabloului!");
}
finally
{
Console.WriteLine("Suma este : " + s);
}
Console.ReadLine();
}

Rezultatele execuiei programului:

Img. 7Depasirea dimensiunilor unui vector

n exemplul dat este aruncat excepia IndexOutOfRangeException, atunci cnd se ncearc


s se acceseze o component inexistent.

14

3. Crearea propriilor excepii


n cazul n care excepiile predefinite nu sunt suficiente, programatorul i poate construi
propriile tipuri. Se recomand ca acestea s fie derivate din System.ApplicationException, care este
derivat direct din System.Exception. Se recomand aceast derivare, deoarece astfel se va face
distincia ntre excepiile aplicaiei i cele de sistem.
Exemplul 5: Crearea excepiei VarstaInvalida
Codul programului:
using System;
//Definirea Exceptiei
class VarstaInvalida : Exception
{
// constructor
public VarstaInvalida(int varsta)
: base(varsta + " nu este o valoare valida pentru varsta.")
{
this.varsta = varsta;
}
private int varsta;
public int Varsta
{
get { return varsta; }
}
}
class Persoana
{
// constructor
public Persoana(string nume, int varsta)
{
this.nume = nume;
this.varsta = varsta;
}
public string Nume
{
get { return nume; }
}
public int Varsta
{
get { return varsta; }
15

set
{
// validare varsta
if (value < 0 || value > 200)
throw new VarstaInvalida(value);
varsta = value;
}
}
string nume;
int varsta;
}
class Program
{
static void Main()
{
// creare obiect
Persoana ionel = new Persoana("Ion", 20);
try
{
Console.Write("Varsta noua:");
ionel.Varsta = int.Parse(Console.ReadLine());
Console.WriteLine("Varsta noua este {0}.", ionel.Varsta);
}
catch (FormatException)
{
Console.WriteLine("Eroare: Varsta trebuie sa fie un intreg.");
}
catch (VarstaInvalida e)
{
Console.WriteLine("Eroare: Varsta trebuie sa fie intre 0 si 200.");
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine("{0} are {1} ani.", ionel.Nume, ionel.Varsta);
}
Console.ReadLine();
}
}

n exemplul dat, prin blocul try se ncearc s se citeasc vrsta de la tastatur, excepiile care
pot aprea sunt:
FormatException irul nu poate fi convertit la un ntreg;
VarstaInvalida vrsta nu este valid.
Rezultatele executiei programului:
16

Img. 8 Excepia VarstaInvalida

La setarea vrstei invalide (Img.8) este aruncat excepia VarstaInvalida, care anun c a
aprut o excepie prin intermediul mesajului Varsta trebuie sa fie intre 0 si 200, precum i mesajul
excepiei -22 nu este o valoare valida pentru varsta, prin intermediul instanei de eroare e.
La ncercarea de a se seta vrstei o valoare ce nu este de tip ntreg, este aruncat excep ia
FormatException, ce anun c valoarea setat nu poate fi convertit n ntreg (Img.9)

Img. 9 Exceptia FormatException

Mesajul din blocul finally se va afia indiferent de ce se ntmpl n blucl try, dac apare o
eroare, atunci vrsta afiat, va fi vrsta setat prin constructor, altfel, se va afia vrsta citit de la
tastatura. (Img. 8, Img.9).

17

Concluzii
Un programator nu trebuie s confunde tratarea excepiilor cu erorile sau bag-urile. Erorile de
run-time pot aprea pentru o varietate de motive, cu toate acestea nu toate erorile trebuie s fie
tratate ca excepii. De exemplu un bag este o eroare de programare care ar trebuie s fie fixat
naintea livrarii codului.
Excepiile nu sunt create pentru a preveni bag-urile, deoarece bag-urile trebuie s fie
eliminate, cu toate c un bag poate s duc la apariia unei excepii. La fel sunt i erorile de utilizare,
adic o eroare n logica de program, care poate duce la o excepie. Cu toate acestea, eroarea ar trebui
s fie abordat nu prin tratarea exceptiilor, ci prin modificarea codului defect.
Excepiile sunt situaiile neasteptate aparute n cadrul sistemului care ruleaza un program.
Programele trebuie s fie pregatite pentru a trata aceste situatii excepionale.
Tratarea excepiilor are ca avantaj evitarea nchiderii anormale a programului. Cand o excepie
va fi aruncat, ea va fi prins undeva, n cod. Dac programul nu va prinde excepia, ea va fi
manipulat de runtime, care o va transforma n eroare i va nchide programul.

18

Bibliografie
1. Rodica Pintea, Adrian Ni, Nicolae Olroiu, Mihai Ttran, Tudor-Ioan Salomie
2.
3.
4.
5.
6.
7.
8.

Introducere n Programarea .Net Framework.


Lucian Sasu Limbajul C#.
http://blog.zeltera.eu/
http://www.dponline.ro/
http://cursuri.cs.pub.ro/
https://tuneam.files.wordpress.com/
https://msdn.microsoft.com/en-us/library/
http://cristianciurea.ase.ro/

19