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
- Il est possible de construire de nouvelles classes d'exceptions personnalisées en héritant d'une des classes du langage, ou à minima de la classe de base Exception.
- Il est aussi possible de lancer une exception personnalisée (comme si c'était une exception propre au langage) à n'importe quel endroit dans le code d'une méthode d'une classe, en instanciant un objet d'exception personnalisé et en le préfixant par le mot clef (raise pour Delphi et throw pour Java et C#).
- Le mécanisme général d'interception des exceptions à travers des gestionnaires d'exceptions try…except ou try…catch s'applique à tous les types d'exceptions y compris les exceptions personnalisées.
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 :
![]()
- La démarche
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.
![]()
- Les classes d'exception
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 :
![]()
- Les blocs lançant éventuellement une exception
Chaque bloc le plus interne peut lancer
(lever) une exception de classe différente
et la propage au niveau supérieur :
![]()
- Les blocs interceptant les exceptions
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 ( );
}
}
}