3.5. Exceptions : C# comparé à Java et Delphi


Plan général:   ...........retour au plan général


1. Similitude et différence


2. Créer et lancer ses propres exceptions


3. Un exemple de traitement en C#


4. Une solution de l'exemple





1. similitude et différence


Nous ne développons pas de cours spécial pour les exceptions en C#, en effet : le langage C# hérite strictement de Java pour la syntaxe et le fonctionnement de base des exceptions et de la simplicité de Delphi dans les types d’exceptions.

C’est pourquoi nous renvoyons le lecteur au chapitre  9.3.2 (exceptions en java) pour une étude complète de la notion d’exception, de leur gestion, de la hiérarchie, de l’ordre d’interception et du redéclenchement d’une exception. Nous figurons ci-dessous un tableau récapitulant les similitudes dans chacun des trois langages :

Delphi

Java

C#

try
  - ...
 
<lignes de code à protéger>
  - ...
except
   on  E : ExxException do begin
     - ...
     <lignes de code réagissant à l’exception>
     - ...
    end;
 - ...
end ;

try
 { - ...
 
<lignes de code à protéger>
  - ...}
catch ( ExxException  E )
   {- ...
     
<lignes de code réagissant à l’exception>
    - ...
   }


fonctionnement identique à C#

try
 { - ...
 
<lignes de code à protéger>
  - ...}
catch ( ExxException  E )
   {- ...
     
<lignes de code réagissant à l’exception>
    - ...
   }


fonctionnement identique à Java

 ATTENTION DIFFERENCE : C# - Java

Seul Java possède deux catégories d'exceptions : les exceptions  vérifiées et les exceptions  non vérifiées. C# comme Delphi possède un mécanisme plus simple qui est équivalent à celui de Java dans le cas des exceptions non vérifiées (implicites) ( la propagation de l'exception est implicitement prise en charge par le système d'exécution).

 

 

2. Créer et lancer ses propres exceptions


Dans les 3 langages la classes de base des exceptions se nomme : Exception

 

 

 



1°) Création d'une nouvelle classe :

 

Delphi

Java

C#

Type
   MonExcept = class (Exception)
    ....
   End;

MonExcept hérite par construction de la propriété public Message de sa mère, en lecture et écriture.

class MonExcept extends Exception
 {
    public MonExcept (String s)
    {
         super(s);
         ..........
     }
 
}

class MonExcept : Exception
 {
    public MonExcept (string s) : base(s)
    {
         .............
     }
 
}
MonExcept hérite par construction de la propriété public Message de sa mère, en lecture seulement.

 



2°) Lancer une MonExcept :

 

 

Delphi

Java

C#

Type
   MonExcept = class (Exception)
      ..........
   End;

classA = class
 Procedure Truc;
end;

Implementation

Procedure classA.Truc;
begin
    …..
   
raise MonExcept.Create ( 'salut' );
   …..
end;

class MonExcept extends Exception
 {
    public MonExcept (String s)    {
         super(s);
         ..........
     }
 }

class classA
 {
    void Truc ( ) throws  MonExcept {
         …..
       throw  new MonExcept (
'salut' );
         …..
    }
 
}

class MonExcept : Exception
 {
    public MonExcept (string s) : base(s)
    {
         .............
     }
 
}

class classA
 {
    void Truc ( )  {
         …..
       throw  new MonExcept (
'salut' );
         …..
    }
 }

 



3°) Intercepter une MonExcept :

          

 

Delphi

Java

C#

Type
   MonExcept = class (Exception)
      ..........
   End;

classB = class
 Procedure Meth;
end;

Implementation

Procedure
classB.Meth;
begin
   …..
   
try
     
 ….. // code à protéger
    except on MonExcept do
      begin
      
….. // code de réaction à l'exception
      end;
   end;

end;

class MonExcept extends Exception
 {
    public MonExcept (String s)    {
         super(s);
         ..........
     }
 
}

class classB
 {
    void Meth ( )  {
         …..
       try
        {
         
….. // code à protéger
        } 
       catch
(MonExcept e) {
             ….. // code de réaction à l'exception
        }
 }

class MonExcept : Exception
 {
    public MonExcept (string s) : base(s)
    {
         .............
     }
 
}

class classB
 {
    void Meth ( )  {
         …..
       try
        {
         
….. // code à protéger
        } 
       catch
(MonExcept e) {
             ….. // code de réaction à l'exception
        }
 }

 

3. Un exemple de traitement en C#

Enoncé : Nous nous proposons de mettre en oeuvre les concepts précédents sur un exemple simulant un traitement de fichier. L'application est composée d'un bloc principal <programme> qui appelle une suite de blocs imbriqués.

 

Les classes en jeu et les blocs de programmes (méthodes) acteurs dans le traitement des exceptions :


<programme>

…<ActionsSurFichier>

…..<AfficheFichier>

……...<ChercheElement>

..............<OuvrirFichier>
--> exception

..............<LireElement>  
--> exception

…..........<FermerFichier>
--> exception

Les trois blocs du dernier niveau les plus internes <OuvrirFichier>, <LireElement> et <FermerFichier> peuvent lancer chacun une exception selon le schéma ci-après :

 
Les éventuelles exceptions lancées par les blocs <OuvrirFichier>,<LireElement> et <FermerFichier> doivent pouvoir se propager aux blocs de niveaux englobant afin d'être interceptables à n'importe quel niveau.

 

 

 
On propose de créer une classe générale d'exception EFichierError héritant de la classe des Exception, puis 3 classes d'exception héritant de cette classe EFichierError : 

 

 

Chaque bloc le plus interne peut lancer

(lever) une exception de classe différente

et la propage au niveau supérieur :

 

 

 

 
Nous proposons par exemple d'intercepter les exceptions dans les deux blocs  <ActionsSurFichier> et <AfficheFichier> :

Le bloc <AfficherFichier>

 

Ce bloc interceptera une exception de type EFichierError, puis la redéclenchera après traitement :

Le bloc <ActionsSurFichier>

 

Ce bloc interceptera une exception de l'un des trois types EOuvertureError,  ELectureError ou EFermetureError :

 

 

 

 

4. Une solution de l’exemple précédent en C#

 
using  System ;
namespace  PrTests
{
 
/* pseudo-Traitement d'un fichier è plusieurs niveaux,
  * avec exception et relance d'exception
  */
 
class  EFichierError  Exception {
    public 
int  typeErr ;
    public 
EFichierError  ( String s,  int  x ): base ( s )  {
   
      typeErr = x ;
    }
}
 

      class  EOuvertureError  EFichierError {
  public 
EOuvertureError ( int  x ): base ("Impossible d'ouvrir le fichier !" ,x )  {  }
}
 
class 
ELectureError  EFichierError{
  public 
ELectureError ( int  x ): base ("Impossible de lire le fichier  !" ,x )  {  }
}
 
class 
EFermetureError  EFichierError{
  public 
EFermetureError ( int  x ): base ("Impossible de fermer le fichier  !" ,x )  {
  }
}
 
//------------------------------------------------------------------------------
 
public class 
PrTransmettre {
  
  void 
TraitementGen ( String s )  {
   
System .Console.WriteLine ("traitement general de l''erreur: " + s );
  }
  
  void 
TraitementSpecif ( String s )  {
   
System .Console.WriteLine ("traitement specifique de l''erreur: " + s );
  }
  
  void 
OuvrirFichier ( )  {
   
System .Console.WriteLine ("  >> Action ouverture...");
   
GenererIncident ( 1 );
   
System .Console.WriteLine ("  >> Fin ouverture.");
  }
  

  

void  LireElement ( )  {
   
System .Console.WriteLine ("  >> Action lecture...");
   
GenererIncident ( 2 );
   
System .Console.WriteLine ("  >> Fin lecture.");
  }
  
  

void  FermerFichier ( )  {
   
System .Console.WriteLine ("  >> Action fermeture...");
   
GenererIncident ( 3 );
   
System .Console.WriteLine ("  >> Fin fermeture.");  
  
}  

   

  
 
 //------------------------------------------------------------------------------------------
  
  
 void  GenererIncident ( int  TypeIncident )   {
   
int  n ;
   
Random nbr  new  Random ( );
   switch (
TypeIncident )
   {
    case 
1 : n nbr.Next ( ) % 4 ;
    
if ( n == 0 )
         throw new 
EOuvertureError ( TypeIncident );
    break;
    case 
2 : n nbr.Next ( ) % 3 ;
    
if ( n == 0 )
         throw new 
ELectureError ( TypeIncident );
    break;
    case 
3 : n = nbr.Next ( ) % 2 ;
    
if ( n == 0 )
         throw new 
EFermetureError ( TypeIncident );
    break;
   }
  }
 
//-----------------------------------------------------------

void  ActionsSurFichier ( )  {
   
System .Console.WriteLine ("Debut du travail sur le fichier.");

  try
    {
     
System .Console.WriteLine (".........");
     
AfficherFichier ( );
    }


    catch(
EOuvertureError E )
    {
     
TraitementSpecif ( E.Message );
    }  


    catch(
ELectureError E )
    {
     
TraitementSpecif ( E.Message );
    }


    catch(
EFermetureError E )
    {
     
TraitementSpecif ( E.Message );
    }

  

      System.Console.WriteLine ("Fin du travail sur le fichier.");
 }

//-----------------------------------------------------------------  

void  AfficherFichier ( )   {


   try     {
     
ChercheElement ( );
    }

    catch( EFichierError E )    {
     
TraitementGen ( E.Message );   

       throw  E ;
    } 

  }



public static void  Main ( string [ ] arg )  {
   
PrTransmettre Obj  new  PrTransmettre ( );
   try     {
     
Obj.ActionsSurFichier ( );
    }
    catch(
EFichierError E )    {
    
System .Console.WriteLine ( " Autre  type  d'Erreur générale Fichier !");
    }
    
System .Console.ReadLine ( );
  }
 }
}