Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Un bloc try est utilisé par les programmeurs C# pour partitionner du code susceptible d’être affecté par une exception. Les blocs catch associés sont utilisés pour gérer les exceptions résultantes. Un bloc finally contient du code qui est exécuté qu'une exception soit levée ou non dans le bloc try
, par exemple la libération de ressources allouées dans le bloc try
. Un try
bloc nécessite un ou plusieurs blocs associés catch
, ou un finally
bloc, ou les deux.
Les exemples suivants montrent une try-catch
instruction, une try-finally
instruction et une try-catch-finally
instruction.
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
// Only catch exceptions that you know how to handle.
// Never catch base class System.Exception without
// rethrowing it at the end of the catch block.
}
try
{
// Code to try goes here.
}
finally
{
// Code to execute after the try block goes here.
}
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
}
finally
{
// Code to execute after the try (and possibly catch) blocks
// goes here.
}
Un bloc try
sans bloc catch
ou bloc finally
entraîne une erreur du compilateur.
Blocs catch
Un catch
bloc peut spécifier le type d’exception à intercepter. La spécification de type est appelée filtre d’exception. Le type d’exception doit être dérivé de Exception. En règle générale, ne spécifiez Exception pas comme filtre d’exception, sauf si vous savez comment gérer toutes les exceptions qui peuvent être levées dans le try
bloc, ou si vous avez inclus une throw
instruction à la fin de votre catch
bloc.
Plusieurs catch
blocs avec différentes classes d’exception peuvent être chaînés ensemble. Les catch
blocs sont évalués de haut en bas dans votre code, mais un catch
seul bloc est exécuté pour chaque exception levée. Le premier catch
bloc qui spécifie le type exact ou une classe de base de l’exception levée est exécuté. Si aucun bloc catch
ne spécifie une classe d’exception correspondante, un bloc catch
sans type est sélectionné, s’il y en a un dans l’instruction. Il est important de positionner catch
les blocs avec les classes d’exception les plus spécifiques (c’est-à-dire les plus dérivées) en premier.
Interceptez les exceptions quand les conditions suivantes sont remplies :
- Vous avez une bonne compréhension de la raison pour laquelle l’exception peut être levée et vous pouvez implémenter une récupération spécifique, par exemple inviter l’utilisateur à entrer un nouveau nom de fichier lorsque vous interceptez un FileNotFoundException objet.
- Vous pouvez créer et lever une exception plus spécifique.
int GetInt(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
- Vous souhaitez gérer partiellement une exception avant de la transmettre pour plus de gestion. Dans l’exemple suivant, un
catch
bloc est utilisé pour ajouter une entrée à un journal des erreurs avant de relancer l’exception.try { // Try to access a resource. } catch (UnauthorizedAccessException e) { // Call a custom error logging procedure. LogError(e); // Re-throw the error. throw; }
Vous pouvez également spécifier des filtres d’exception pour ajouter une expression booléenne à une clause catch. Les filtres d’exceptions indiquent qu’une clause catch spécifique correspond uniquement lorsque cette condition est vraie. Dans l’exemple suivant, les deux clauses catch utilisent la même classe d’exception, mais une condition supplémentaire est vérifiée pour créer un message d’erreur différent :
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch (IndexOutOfRangeException e) when (index < 0)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be negative.", e);
}
catch (IndexOutOfRangeException e)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be greater than the array size.", e);
}
}
Un filtre d’exceptions qui retourne false
toujours peut être utilisé pour examiner toutes les exceptions, mais pas les traiter. Une utilisation classique consiste à journaliser les exceptions :
public class ExceptionFilter
{
public static void Main()
{
try
{
string? s = null;
Console.WriteLine(s.Length);
}
catch (Exception e) when (LogException(e))
{
}
Console.WriteLine("Exception must have been handled");
}
private static bool LogException(Exception e)
{
Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
Console.WriteLine($"\tMessage: {e.Message}");
return false;
}
}
La méthode LogException
retourne toujours false
, aucune clause catch
utilisant ce filtre d’exception ne correspond. La clause catch peut être générale et utiliser System.Exception. Les clauses ultérieures peuvent traiter des classes d’exception plus spécifiques.
Blocs Finally
Un finally
bloc vous permet de nettoyer les actions effectuées dans un try
bloc. S’il est présent, le finally
bloc s’exécute en dernier, après le try
bloc et tout bloc correspondant catch
. Un finally
bloc s’exécute toujours, qu’une exception soit levée ou qu’un catch
bloc correspondant au type d’exception soit trouvé.
Le finally
bloc peut être utilisé pour libérer des ressources telles que des flux de fichiers, des connexions de base de données et des handles graphiques sans attendre que le garbage collector dans l’exécution finalise les objets.
Dans l’exemple suivant, le finally
bloc est utilisé pour fermer un fichier ouvert dans le try
bloc. Notez que l’état du handle de fichier est vérifié avant la fermeture du fichier. Si le try
bloc ne peut pas ouvrir le fichier, le handle de fichier a toujours la valeur null
et le finally
bloc n’essaie pas de le fermer. Au lieu de cela, si le fichier est ouvert correctement dans le try
bloc, le finally
bloc ferme le fichier ouvert.
FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
file?.Close();
}
Spécification du langage C#
Pour plus d’informations, consultez Exceptions et l’instruction Try dans la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.