+ All Categories
Home > Documents > curs .NET 5.pdf

curs .NET 5.pdf

Date post: 14-Apr-2018
Category:
Upload: andera4u
View: 267 times
Download: 1 times
Share this document with a friend

of 23

Transcript
  • 7/27/2019 curs .NET 5.pdf

    1/23

    Exceptii

    O linie de cod poate sa nu se execute corect din diverse motive: depasire aritmetica,

    depasire stiva, memorie insuficienta, indici in afara intervalului, etc.O aplicatie ce si-ar propune sa verifice toate (sau aproape toate) posibilitatile ce pot

    aparea in executarea unei linii de cod si-ar pierde din claritate, ar fi foarte greu deintretinut, iar mare parte din timp procesor s-ar consuma cu aceste verificari.

    Realizarea unei astfel de aplicatii este aproape imposibila.Folosind exceptiile nu este nevoie sa scriem cod pentru a detecta toate aceste posibile

    caderi. In plus codul se executa mai rapid.

    Trebuie spus de la inceput ca exceptiile genereaza alte probleme care trebuiesc rezolvate.

    Dintre avantajele introducerii exceptiilor amintim :

    abilitatea de a mentine cod clar si de a intelege logica aplicatiei mai usor;

    posibilitatea de a detecta si localiza bug-uri in cod;Cand apare o cadere, CLR scaneaza stiva firului cautind codul ce ar putea trata

    exceptia. Daca nu exista un asemenea cod, primim o notificare unhandled exception.Folosirea incorecta a tratarii execeptiilor poate crea neplaceri mai mari decat nefolosirea

    lor.

    Evolutia manipularii exceptiilor

    Win32 API si COM nu folosesc exceptiile pentru a notifica utilizatorul despre problema

    aparuta. Multe functii returneaza FALSE sau NULL sau o valoare de tip HRESULT

    pentru a indica ca ceva nu s-a executat corect. De altfel nu s-a standardizat tratareaerorilor in Win32 API. La inceput C si C++ nu suportau exceptiile.

    Metoda veche de raportare a erorilor se limita la un numar pe 32 de biti. In marea

    majoritate a cazurilor mesajele nu sunt clare si nu ofera suficienta informatie pentru adetecta ce anume s-a intimplat.

    Din acest punct de vedere mecanismul de manipulare al exceptiilor ofera mai multe

    avantaje:O exceptie include un sir de caractere ce o descrie.

    Sirul de caractere contine o cale catre apelul ce a declansat anomalia. Informatiile se

    gasesc pe stiva.

    Exceptiile nu pot fi ignorate.

    Daca o metoda arunca o exceptie, aceasta inseamna ca nu lucreaza asa cum ar trebui.Daca aplicatia nu trateaza exceptia, CLR termina aplicatia.

    Toate metodele definite de tipurile din cadrul de lucru .NET arunca exceptii pentru aindica ca anumite presupuneri au fost incalcate. Nu se returneaza nici o valoare de stare.

  • 7/27/2019 curs .NET 5.pdf

    2/23

    Mecanica manipularii exceptiilor

    Mecanismul de manipulare al exceptiilor cadrului de lucru .NET este construit folosind

    Structured Exception Handling (SEH).

    Urmatorul cod C# arata o folosire standard a mecanismului de tratare al exceptiilor.

    void SomeMethod()

    {

    try

    {

    // aici scriem codul ce vrem sa-l protejam (supus verificarii)

    }

    catch (InvalidCastException)

    {

    // Aici este codul ce se va executa daca apare exceptia

    // InvalidCastException sau orice exceptie a unui

    // tip derivat din InvalidCastException.

    }

    catch (NullReferenceException)

    {

    // Aici este codul ce se va executa daca apare exceptia

    // NullReferenceException sau orice exceptie a unui

    // tip derivat din NullReferenceException.

    }

    catch (Exception e)

    {

    // In interiorul acestui bloc scriem codul care se executa

    // pentru o exceptie CLS-compliant (conforma cu CLS).

    // In mod normal se rearunca exceptia.

    throw;

    }catch

    {

    // Aici este codul ce se va executa pentru price tip de exceptie

    // In mod normal se rearunca exceptia.

    throw;

    }

    finally

    {

    // Acest cod este garantat ca se executa totdeauna, dar

    // binenteles exista cateva exceptii de la aceasta presupunere.

    // Codul de aici se executa indiferent daca a aparut

    // sau nu o exceptie.

    // Este asa numitul cod de curatare, mai precis de terminare

    // a unor operatii incepute in bocul try.

    }

    //

    // In continuare este codul ce se executa cand nu// a aparut nici o exceptie.

    }

  • 7/27/2019 curs .NET 5.pdf

    3/23

    In mod normal in cod avem un bloctry, unul sau mai multe blocuricatch si optional

    un blocfinally.

    Exemplu:

    using System;//includes System.Exception

    class ExceptionApp

    {

    public TestMethod( int i, int j)

    {

    try

    {

    ...

    ...

    // Functia apelata poate arunca o exceptie.

    ExceptionMethod(); //*1

    ...

    ...

    int k=0;

    // Operatiile pot arunca exceptii

    // Daca j = 0 atunci avem impartire la zero

    k = i/j; //*2

    ...

    ...

    //Constient, se arunca o exceptie, ce tine de logica aplicatiei

    if( k == 0)

    throw new Exception(); //*3

    }

    catch (Exception e) //*4 se prind toate exceptiile

    {

    }

    Console.Writeline("Code after exception"); // *5

    }

    }

    Blocul try

    In general un bloc try contine cod ce are nevoie de operatii de terminare corecta(curatare) sau operatii de tratare a exceptiilor.

    Codul pentru terminare corecta (de ex. inchiderea unui fisier) trebuie plasat in blocul

    finally.Codul de tratare al exceptiilor trebuie plasat in unul sau mai multe blocuri catch. Fiecare

    bloc catch identifica un anumit tip de exceptie.

  • 7/27/2019 curs .NET 5.pdf

    4/23

    Putem crea cate un bloc catch pentru orice tip de eveniment pentru care avem

    posibilitatea de a corecta exceptia aparuta sau a obtine mai multe informatii despreaceasta. Aceste informatii pot ajuta pentru depistarea unui bug sau neindeplinirea unor

    conditii de sistem (de ex. adresa IP).

    Un bloc try trebuie sa fie asociat cu cel putin un bloc catch sau finally.

    Blocul catch

    Blocul catch contine cod ce se executa cand apare o exceptie. Daca codul din blocul try

    nu cauzeaza o exceptie, atunci codul din blocul catch nu se executa. Daca exista bloculfinally atunci codul se executa indiferent daca s-a aruncat sau nu o exceptie. Daca nu a

    aparut o exceptie atunci executia continua cu codul de dupa blocul finally.

    Expresia dintre paranteze de la blocul catch se numeste filtru exceptie.Exceptia filtru este un tip ce reprezinta o situatie exceptionala pe care dezvoltatorul a

    anticipat-o si poate sa o trateze intr-un anume fel (poate iesi din aceasta situatie).

    In C#, tipul din filtru trebuie sa fie System.Exception sau un tip derivat din

    System.Exception.

    Blocurile catch sunt tratate in mod secvential, de sus in jos, deci blocurile catch pentru

    tratarea exceptiilor specifice trebuie plasate cat mai aproape de blocul try.

    Daca o exceptie este aruncata de codul din blocul try (sau orice metoda apelata din cadrulacestuia), CLR cauta blocurile catch al caror filtru se potriveste cu exceptia aruncata.

    Daca nu exista un asemenea bloc catch, atunci CLR cauta in stiva un bloc catch al carui

    filtru se potriveste. Daca cautarea s-a terminat si nu s-a gasit un asemenea bloc atunciCLR opreste aplicatia si afiseaza mesajul Unhandled exception.

    CLR pastreaza o arborescenta a tuturor metodelor apelate din blocul try.

    Cand s-a localizat un bloc catch ce trateaza excepia (filtrul se potriveste), CLR executacodul din toate blocurile finally, plecand de la acela al blocului try ce a generat exceptia

    si oprindu-se la acela al blocului try ce contine blocul catch ce trateaza exceptia.

    Codul din ultimul bloc finally se va executa dupa ce s-a executat codul din blocul catch.

    In C#, un filtru catch poate specifica o variabila de tip exceptie. Aceasta variabila se

    refera la un obiect derivat din System.Exception ce a aruncat aceasta exceptie. Codul din

    blocul catch poate referi aceasta variabila pentru a obtine informatii suplimentare despreexceptie.

    La sfarsitul ultimului bloc catch avem urmatoarele posibilitati:

    1. rearuncarea aceleasi exceptii;2. aruncarea unei alte exceptii;3. sa lasam ca firul sa termine cautarea aici.

    In primele doua situatii, CLR va cauta in continuare pe stiva un bloc catch ce poate trata

    exceptia.

  • 7/27/2019 curs .NET 5.pdf

    5/23

    In ultima situatie se va executa codul din blocul finally si apoi se continua in secventa cu

    codul ce urmeaza acestui bloc. Daca nu exista un bloc finally, se continua executia cucodul ce urmeaza ultimului bloc catch.

    Blocul finally

    Un bloc finally contine cod ce este garantat ( ?!) ca se va executa.

    Exemplu:

    void ReadData(String pathname)

    {

    FileStream fs = null;

    try

    {

    fs = new FileStream(pathname, FileMode.Open);

    // Procesare date din fisier

    }

    catch (OverflowException){

    // Inside this catch block is where you put code that recovers

    // from an OverflowException (or any exception type derived

    // from OverflowException).

    }

    finally

    {

    // Make sure that the file gets closed.

    if (fs != null) fs.Close();

    }

    }

    Indiferent de cum se executa codul din blocul try, codul din blocul finally se va executa.Blocul finally trebuie sa apara dupa toate blocurile catch asociate cu blocul try.

    Nu se arunca exceptii in blocul finally.

    Riscul este de a construi o aplicatie ce nu se mai termina.

    Ce este o exceptie?

    Termenul eroare indica ca programatorul a facut ceva gresit.

    Exceptiile nu indica neaparat o eroare in cod.

    Exceptiile nu conduc neaparat la oprirea executiei unei aplicatii.

    O exceptie poate fi definita ca fiind violarea unei presupuneri implicite asupra unei

    interfete (J. Richter).

    De exemplu construirea unui tip nu poate cuprinde toate situatiile in care acesta poate fi

    folosit. Cazurile care nu sunt implementate dar se incearca a fi folosite vor arunca

    anumite exceptii in ideea de a nu folosi tipul respectiv altfel decat a fost proiectat.

  • 7/27/2019 curs .NET 5.pdf

    6/23

    Trebuie sa facem distinctie intre exceptiile aruncate de aplicatie si cele aruncate de CLR.Comportarile aplicatiei sunt diferite functie de cine a aruncat exceptia.

    CLR arunca exceptii, de ex. System.StackOverflowException, sau

    System.OutOfMemoryException, sau System.ExecutionEngineException.

    In aceste situatii este posibil ca codul din blocul finally sa nu se poata executa.

    OutOfMemoryException = este aruncata aceasta exceptie cand construim un nou obiect

    si nu exista memorie suficienta. In acest caz procesul se termina imediat, codul din bloculfinally se executa. Daca exceptia este aruncata de CLR atunci procesul se termina imediat

    si aplicatia nu mai este in stare sa prinda aceasta exceptie si blocul finally nu se mai

    executa.

    StackOverflowException = CLR arunca aceasta exceptie cand unfir a utilizat tot spatiul

    pentru stiva. Aplicatia poate prinde aceasta exceptie dar codul din blocul finally nu se vaexecuta pentru ca si asta are nevoie de spatiu pe stiva.Fiecare bloc catch ce prinde aceasta exceptie trebuie sa o arunce in continuare (rethrow)

    pentru a da sansa CLR-ului sa termine procesul.

    Daca exceptia apare in CLR, aplicatia nu poate prinde aceasta exceptie si blocul finallynu se executa. In acest caz CLR termina procesul sau lanseaza un debugger.

    ExecutionEngineException = CLR arunca aceasta exceptie cand detecteaza ca structurile

    sale de date interne sunt corupte sau are anumite bug-uri. CLR-ul termina procesul sau valansa un debugger pentru proces. Nu se executa nici un bloc catch si nici finally.

    Clasa System.Exception

    Modelul de tratare al exceptiilor este bazat pe reprezentarea exceptiilor ca obiecte sisepararea codului aplicatiei de codul de tratatre al exceptiilor.

    Un bloc catch ce trateaza System.Exception trebuie sa fie ultimul bloc pentru try.

    Ordinea blocurilor catch ce trateaza o exceptie va fi urmatoarea : intai exceptia pentru

    tipul derivat si apoi exceptia pentru clasa de baza (blocurile catch se trateaza secvential,

    iar cautarea se opreste dupa primul bloc catch ce trateaza exceptia).

    Exemplu (cod incorect al doilea bloc catch nu va fi executat niciodata pentru ca

    System.Web.HttpException este derivat din System.Exception).try{// Code which can cause a web exception or arithmetic exception.}catch (System.Exception ex){

    MessageBox.Show ( "An exception occurred." );}catch (System.Web.HttpException ex)

  • 7/27/2019 curs .NET 5.pdf

    7/23

    {MessageBox.Show ( "A web exception occurred." );

    }

    Acelasi exemplu, dar de aceasta data corect:

    try{// Code which can cause a web exception or arithmetic exception.}catch (System.Web.HttpException ex){

    MessageBox.Show ( "A web exception occurred." );}catch(System.Exception ex){

    MessageBox.Show ( "An exception occurred." );}

    In clasa Exception exista doua categorii de exceptii:

    clase exceptii predefinite de CLR, derivate din SystemException.

    Clase exceptii definite de utilizator la nivel de aplicatie si derivate din

    ApplicationException.

    CLR permite o instanta de orice tip sa fie aruncata pentru o exceptie.

    Tipurile de exceptii ce sunt derivate din System.Exception se numesc CLS-compliant(conforme cu CLS).

    Tipul System.Exception este descris in continuare.

    Message - Read-only String Indica de ce a fost aruncata exceptia.

    Source - Read/write String Contine numele assembly ce a generat exceptia.

    StackTrace - Read-only String Contine numele si signatura metodei apelate ce a dus la

    aruncarea exceptiei.

    TargetSite - Read-only MethodBase Contine metoda ce a generat exceptia.

    HelpLink - Read-only String Contine un URL la documentatia exceptiei.

    InnerException - Read-only Exception Indica exceptia anterioara daca exceptia

    curenta a fost generata in timp ce manipula o alta exceptie.

    Metoda GetBaseException returneaza originea exceptiei.

    HResult - Read/write Int32 Proprietate protected, folosita cand exista cod managed siunmanaged COM.

  • 7/27/2019 curs .NET 5.pdf

    8/23

    Cateva clase pentru exceptii definite in FCL.

    Class Description

    AppDomainUnloadedException The exception that is thrown when

    an attempt is made to access an

    unloaded application domain.

    ApplicationException The exception that is thrown when

    a non-fatal application error

    occurs.

    ArgumentException The exception that is thrown when

    one of the arguments provided to a

    method is not valid.

    ArgumentNullException The exception that is thrown when

    a null reference is passed to a

    method that does not accept it as

    a valid argument.

    ArgumentOutOfRangeException The exception that is thrown when

    the value of an argument is

    outside the allowable range of

    values as defined by the invoked

    method.

    ArithmeticException The exception that is thrown for

    errors in an arithmetic, casting, or

    conversion operation.

    ArrayTypeMismatchException The exception that is thrown when

    an attempt is made to store an

    element of the wrong type within

    an array.

  • 7/27/2019 curs .NET 5.pdf

    9/23

    BadImageFormatException The exception that is thrown when

    the file image of a DLL or an

    executable program is invalid.

    CannotUnloadAppDomainException The exception that is thrown when

    an attempt to unload an

    application domain fails.

    ContextMarshalException The exception that is thrown when

    an attempt to marshal an object

    across a context boundary fails.

    DivideByZeroException The exception that is thrown when

    there is an attempt to divide an

    integral or decimal value by zero.

    DllNotFoundException The exception that is thrown when

    a DLL specified in a DLL import

    cannot be found.

    DuplicateWaitObjectException The exception that is thrown when

    an object appears more than once

    in an array of synchronization

    objects.

    EntryPointNotFoundException The exception that is thrown when

    an attempt to load a class fails due

    to the absence of an entry method.

    Exception Defines the base class for all

    exceptions.

    ExecutionEngineException The exception that is thrown when

    there is an internal error in the

    execution engine of the common

  • 7/27/2019 curs .NET 5.pdf

    10/23

    language runtime. This class

    cannot be inherited.

    FieldAccessException The exception that is thrown whenthere is an illegal attempt to

    access a private or protected field

    inside a class.

    FormatException The exception that is thrown when

    the format of an argument does

    not meet the parameter

    specifications of the invoked

    method.

    IndexOutOfRangeException The exception that is thrown when

    an attempt is made to access an

    element of an array with an index

    that is outside the bounds of the

    array. This class cannot be

    inherited.

    InvalidOperationException The exception that is thrown when

    a method call is invalid for the

    object's current state.

    InvalidProgramException The exception that is thrown when

    a program contains an invalid IL or

    metadata. Generally this indicates

    a bug in a compiler.

    MemberAccessException The exception that is thrown when

    an attempt to access a class

    member fails.

  • 7/27/2019 curs .NET 5.pdf

    11/23

    MethodAccessException The exception that is thrown when

    there is an illegal attempt to

    access a private or protected

    method inside a class.

    MissingFieldException The exception that is thrown when

    there is an attempt to dynamically

    access a field that does not exist.

    MissingMemberException The exception that is thrown when

    there is an attempt to dynamically

    access a class member that does

    not exist.

    MissingMethodException The exception that is thrown when

    there is an attempt to dynamically

    access a method that does not

    exist.

    MulticastNotSupportedException The exception that is thrown when

    there is an attempt to combine two

    instances of a non-combinable

    delegate type unless one of the

    operands is a null reference. This

    class cannot be inherited.

    NotFiniteNumberException The exception that is thrown when

    a floating-point value is positive

    infinity, negative infinity, or Not-a-

    Number (NaN).

    NotImplementedException The exception that is thrown when

    a requested method or operation is

    not implemented.

  • 7/27/2019 curs .NET 5.pdf

    12/23

    NotSupportedException The exception that is thrown when

    an invoked method is not

    supported, or when there is an

    attempt to read, seek, or write to a

    stream that does not support the

    invoked functionality.

    NullReferenceException The exception that is thrown when

    there is an attempt to dereference

    a null object reference.

    ObjectDisposedException [To be supplied by Microsoft.]

    OutOfMemoryException The exception that is thrown when

    there is not enough memory to

    continue the execution of a

    program.

    OverflowException The exception that is thrown when

    an arithmetic, casting, or

    conversion operation in a checked

    context results in an overflow.

    PlatformNotSupportedException The exception that is thrown when

    a feature does not run on a

    particular platform.

    RankException The exception that is thrown when

    an array with the wrong number of

    dimensions is passed to a method.

    StackOverflowException The exception that is thrown when

    the execution stack overflows by

    having too many pending method

    calls. This class cannot be

  • 7/27/2019 curs .NET 5.pdf

    13/23

    inherited.

    SystemException Defines the base class forpredefined exceptions in the

    System namespace.

    TypeInitializationException The exception that is thrown as a

    wrapper around the exception

    thrown by the class initializer. This

    class cannot be inherited.

    TypeLoadException The exception that is thrown when

    type-loading failures occur.

    TypeUnloadedException The exception that is thrown when

    there is an attempt to access an

    unloaded class.

    UnauthorizedAccessException The exception that is thrown when

    the operating system deniesaccess for reasons involving an IO

    error and some kinds of security

    errors.

    UriFormatException The exception that is thrown when

    an invalid Uniform Resource

    Identifier (URI) is detected.

    ApplicationException este aruncata de un program al utilizatorului si nu de CLR. In

    mod normal exceptiile create de utilizator ar trebui derivate din acest tip.

    ApplicationException diferentiaza exceptiile definite de utilizator decele definite de

    sistem.

    ApplicationException nu furnizeaza informatii despre cauza exceptiei.

  • 7/27/2019 curs .NET 5.pdf

    14/23

    In mod normal nu se arunca o asemenea exceptie de catre aplicatie, dar in cazul cand se

    face acest lucru se va pasa constructorului clasei un mesaj ce va descrie cauza aparitieiexceptiei.

    Descrierea membrilor clasei conform documentatiei Microsoft este urmatoarea:

    !"

    #$%"&'"

    %"&

    '

    ()%"&

    ')

    %"& '"*

    %"& ')""

    )%"&'

    +%"&

    ,*

    +

    '-%"&

    ./"+

    '#%"&

    ""/"))

    '*,%"&

    ./

    !""

    '%"&

    '"

    )%"& )"

  • 7/27/2019 curs .NET 5.pdf

    15/23

    !"

    #0%"& '#01$/)"

    !%"&

    *"""))

    233/"!)

    (

    Clasa SystemException derivata din Exception

    !"

    #$%"&'"

    %"&

    '

    ()%"&

    ')

    %"& '"*

    %"&')""

    )%"&

    '

    +%"&

    ,*+

    '-%"&./"+

  • 7/27/2019 curs .NET 5.pdf

    16/23

    '#%"&

    ""/"))

    '*,%"& ./!""

    '%"&

    '"

    )%"&

    )"

    !"

    #0%"&'#01$/)"

    !%"&

    *"""))

    233/"!)

    (%"&

    "*

    Clase exceptii des utilizate

    System.ArithmeticException exceptii ce apar in timpul operatiilor aritmetice, cum ar fi

    System.DivideByZeroException and System.OverflowException.

    System.ArrayTypeMismatchException - ArrayTypeMismatchException este aruncata

    cand un obiect incompatibil se incearca a fi memorat intr-un Array.

    System.DivideByZeroException incercare de impartire prin zero.

    System.IndexOutOfRangeException - IndexOutOfRangeException este aruncata cand se

  • 7/27/2019 curs .NET 5.pdf

    17/23

    incearca sa se acceseze un tablou folosind un index mai mic ca zero sau in afara

    intervalului tabloului.

    System.InvalidCastException aruncata cand o conversie implicita de la tipul de baza sau

    interfata la tipul derivat nu se executa corect in momentul executiei.

    System.NullReferenceException aruncata cand se foloseste o referinta null la un obiect

    pentru a-l accesa.

    System.OutOfMemoryException - OutOfMemoryException este aruncata cand operatia

    'new' (crearea unui nou obiect) nu se executa cu succes pentru ca nu exista suficientamemorie.

    System.OverflowException - OverflowException este aruncata cand apare depasire la

    executia unei operatii aritmetice.

    System.StackOverflowException - StackOverflowException este aruncata cand cand stiva

    de executie este prea mica pentru a executa toate apelurile initiate (probabil buclainfinita).

    ArgumentException exceptie aruncata cand un argument furnizat unei metode este

    invalid.

    CLR arunca exceptii pentru tipurile derivate din SystemException.

    O parte dintre aceste exceptii nu semnaleaza situatii fatale, o alta parte da.

    Metodele definite de tipurile din FCL sunt presupuse ca arunca exceptii derivate din

    System.Exception.

    Exemplu:

    using System;

    public class MyClass {}

    public class ArgExceptionExample {

    public static void Main() {

    MyClass my = new MyClass();

    string s = "sometext";

    try {

    int i = s.CompareTo(my);

    }

    catch (Exception e) {

    Console.WriteLine("Error: {0}",e.ToString());

    }

    }

    }

    Iesirea este:

    Error: System.ArgumentException: Object must be of type String.

    at System.String.CompareTo(Object value)

    at ArgExceptionExample.Main()

  • 7/27/2019 curs .NET 5.pdf

    18/23

    Definirea claselor de exceptii

    Prin conventie numele unui tip exceptie ar trebui sa se termine cu Exception.

    Metodele ar trebui sa-si verifice argumentele inainte de a le folosi.

    Clasele din FCL ce pot fi folosite pentru acest lucru sunt: ArgumentNullException,

    ArgumentOutOfRangeException

    DuplicateWaitObjectException.

    Nu se va scrie cod ce va arunca o exceptie de tipul Exception, ApplicationException, sau

    SystemException.

    Exemplu:

    class SomeType

    {

    public void SomeMethod(Object o)

    {

    if (!((o is ICloneable) && (o is IComparable)))

    throw new LipsaInterfataException(...);

    // urmeaza cod

    }

    }

    Aici avem tipul LipsaInterfataException. Cum il definim?

    Singura regula de care trebuie sa tinem seama este cea referitoare la efectele colaterale.

    Daca derivam aceasta exceptie din ArgumentException, atunci codul existent cecapteaza aceasta exceptie va capta si noua exceptie.

    Cand definim acest tip trebuie sa vedem cu cine se aseamana dintre exceptiile existente,asemanare in sensul metodei de tratare a exceptiei.Daca derivam tipul din Exception nu exista prea multe informatii despre exceptia

    aruncata.

    Cel mai indicat este sa ne gandim la efectele colaterale decat la cele directe cand derivamun tip exceptie.

    Clasa de baza Exception defineste trei constructori:

    1. unul implicit ce seteaza toate campurile si proprietatile la valori implicite;2. un ctor cu un parametru de tip String ce creaza o instanta a tipului si seteaza un

    mesaj specific.

    3. un ctor cu doi parametri: un String si o instanta a unui tip derivat din Exception ceseteaza un mesaj si o exceptie interna.

    Daca adaugam campuri la un tip exceptie acestia trebuiesc initializati in constructor.

    ExempluAruncarea si tratarea unei exceptii ce face referinta la inner Exception.using System;

    public class MyAppException:ApplicationException

  • 7/27/2019 curs .NET 5.pdf

    19/23

    {

    public MyAppException (String message) : base (message) {}

    public MyAppException (String message, Exception inner) :

    base(message,inner) {}

    }

    public class ExceptExample

    {

    public void ThrowInner ()

    {

    throw new MyAppException("ExceptExample inner exception");

    }

    public void CatchInner()

    {

    try

    {

    this.ThrowInner();

    }

    catch (Exception e)

    {

    throw new MyAppException("Error caused by tryingThrowInner.",e);

    }

    }

    }

    public class Test

    {

    public static void Main()

    {

    ExceptExample testInstance = new ExceptExample();

    try

    {

    testInstance.CatchInner();

    }

    catch(Exception e)

    {

    Console.WriteLine ("In Main catch block. Caught: {0}",

    e.Message);

    Console.WriteLine ("Inner Exception is {0}",e.InnerException);

    }

    }

    }

    Iesirea este:In Main catch block. Caught: Error caused by trying ThrowInner.

    Inner Exception is MyAppException: ExceptExample inner exception

    at ExceptExample.ThrowInner()

    at ExceptExample.CatchInner()

    Exemplu (2) de definire a unei exceptii

    using System;

    using System.IO;

  • 7/27/2019 curs .NET 5.pdf

    20/23

    using System.Runtime.Serialization;

    using System.Runtime.Serialization.Formatters.Soap;

    // Allow instances of DiskFullException to be serialized.

    [Serializable]

    sealed class DiskFullException : Exception, ISerializable

    {

    // The three public constructors

    public DiskFullException()

    : base()

    { // Call base constructor. }

    public DiskFullException(String message)

    : base(message)

    { // Call base constructor. }

    public DiskFullException(String message, Exception innerException)

    : base(message, innerException)

    { // Call base constructor. }

    // Define a private field.

    private String diskpath;

    // Define a read-only property that returns the field.

    public String DiskPath { get { return diskpath; } }

    // Override the public Message property so that the

    // field is included in the message.

    public override String Message

    {

    get

    {

    String msg = base.Message;

    if (diskpath != null)

    msg += Environment.NewLine + "Disk Path: " + diskpath;

    return msg;

    }

    }

    // Because at least one field is defined, define the

    // special deserialization constructor. Because this

    // class is sealed, this constructor is private. If this

    // class is not sealed, this constructor should be protected.

    private DiskFullException(SerializationInfo info,

    StreamingContext context)

    : base(info, context)

    { // Let the base deserialize its fields.

    // Deserialize each field.

    diskpath = info.GetString("DiskPath");}

    // Because at least one field is defined,

    // define the serialization method.

    void ISerializable.GetObjectData(SerializationInfo info,

    StreamingContext context)

    {

    // Serialize each field.

  • 7/27/2019 curs .NET 5.pdf

    21/23

    info.AddValue("DiskPath", diskpath);

    // Let the base type serialize its fields.

    base.GetObjectData(info, context);

    }

    // Define additional constructors that set the field.

    public DiskFullException(String message, String diskpath)

    : this(message) { // Call another constructor.

    this.diskpath = diskpath;

    }

    public DiskFullException(String message, String diskpath,

    Exception innerException)

    : this(message, innerException) { // Call another constructor.

    this.diskpath = diskpath;

    }

    }

    // The following code tests the serialization of the exception.

    class App {

    static void Main() {

    // Construct a DiskFullException object, and serialize it.DiskFullException e =

    new DiskFullException("The disk volume is full", @"C:\");

    FileStream fs = new FileStream(@"Test", FileMode.Create);

    IFormatter f = new SoapFormatter();

    f.Serialize(fs, e);

    fs.Close();

    // Deserialize the DiskFullException object, and check its fields.

    fs = new FileStream(@"Test", FileMode.Open);

    e = (DiskFullException) f.Deserialize(fs);

    fs.Close();

    Console.WriteLine("Type: {1}{0}DiskPath: {2}{0}Message: {3}",

    Environment.NewLine, e.GetType(), e.DiskPath, e.Message);

    }

    }

    Un cod corect de serializare (fisierul nu ramine intr-o stare incorecta, se aduce la starea

    de dinanintea aparitiei exceptiei):

    public void SerializeObjectGraph(FileStream fs,

    IFormatter formatter, Object rootObj) {

    // Save the current position of the file.

    Int64 beforeSerialization = fs.Position;

    try {

    // Attempt to serialize the object graph to the file.

    formatter.Serialize(fs, rootObj);

    }catch { // Catch all CLS and non-CLS exceptions.

    // If ANYTHING goes wrong, reset the file back to a good state.

    fs.Position = beforeSerialization;

    // Truncate the file.

    fs.SetLength(fs.Position);

    // NOTE: The preceding code isnt in a finally block because

    // the stream should be reset only when serialization fails.

    // Let the caller(s) know what happened by

    // rethrowing the SAME exception.

  • 7/27/2019 curs .NET 5.pdf

    22/23

    throw;

    }

    }

    Exemplu (3) de definire a unei exceptii :

    /** Created by SharpDevelop.

    * User: info

    * Date: 11/4/2004

    * Time: 9:21 AM

    *

    * To change this template use Tools | Options | Coding | Edit Standard

    Headers.

    */

    using System;

    using System.IO;

    public class CustomException : Exception

    {

    object extraInfo;

    public CustomException(string message, object extra) :base(message)

    {

    extraInfo = extra;

    }

    public override string ToString()

    {

    return "CustomException: " +

    extraInfo.ToString() + "" +

    base.Message + "" +

    base.StackTrace;

    }}

    class CustomExceptionGenerator

    {

    static voidMain()

    {

    try

    {

    SomeMethod();

    }

    catch (CustomException ce)

    {

    Console.WriteLine(ce.ToString());

    }

    Console.ReadLine();

    }

    public static void SomeMethod()

    {

    //something went wrong

    // Daca aici adaugam urmatorul cod:

  • 7/27/2019 curs .NET 5.pdf

    23/23

    //

    // int i, j,k ;

    // i = 10 ;

    // j = 0 ;

    // k = i/j ;

    //

    // atunci apare Unhandled Exception

    // si apoi exceptia creata.

    //

    throw new CustomException("Something went wrong", "ExtraInfo");

    }

    }

    Iesirea este :

    CustomException: ExtraInfo

    Something went wrongat CustomExceptionGenerator.SomeMethod() in c:\Documents and Settings\info\My

    Documents\SharpDevelop Projects\p5_exception1\Main.cs:line 49at CustomExceptionGenerator.Main() in c:\Documents and Settings\info\My Docum

    ents\SharpDevelop Projects\p5_exception1\Main.cs:line 36

    Ascunderea detaliilor de implementare

    Exemplu (din exemple Microsft si reluat in foarte multe articole pe Internet) :

    Acest exemplu arata cum ar trebui sa renuntam la validarea parametrilor metodelor si

    folosirea exceptiilor in cadrul codului. Oricum decizia finala sta in mina programatorului.

    public Int32 SomeMethod(Int32 x)

    {try

    {

    return 100 / x;

    }

    catch (DivideByZeroException e)

    {

    throw new ArgumentOutOfRangeException("x", x,

    "x cant be 0", e);

    }

    }

    Exceptii netratate = echivalent cu lipsa blocului catch.


Recommended