En Java, le mot clé throws
permet à une méthode de déclarer qu'elle ne gérera pas une exception seule, mais la jettera plutôt à la méthode appelante.
Existe-t-il un mot-clé/attribut similaire en C #?
S'il n'y a pas d'équivalent, comment pouvez-vous obtenir le même effet (ou un effet similaire)?
En Java, vous devez soit gérer une exception, soit marquer la méthode comme pouvant la lever à l'aide du mot clé throws
.
C # n'a pas ce mot-clé ou un mot-clé équivalent, comme en C #, si vous ne gérez pas d'exception, il bouillonnera jusqu'à ce qu'il soit intercepté ou sinon il terminera le programme.
Si vous souhaitez le gérer, puis relancez, vous pouvez effectuer les opérations suivantes:
try
{
// code that throws an exception
}
catch(ArgumentNullException ex)
{
// code that handles the exception
throw;
}
L'op pose des questions sur l'équivalent C = de Java throws
clause - pas sur le throw
mot-clé. Ceci est utilisé dans les signatures de méthode en Java pour indiquer qu'une exception vérifiée peut être levée.
En C #, il n'y a pas d'équivalent direct d'une exception Java vérifiée. C # n'a pas de clause de signature de méthode équivalente.
// Java - need to have throws clause if IOException not handled
public void readFile() throws Java.io.IOException {
...not explicitly handling Java.io.IOException...
}
se traduit par
// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile()
{
...not explicitly handling System.IO.IOException...
}
Oui, c'est un vieux fil de discussion, mais je trouve souvent des fils de discussion anciens lorsque je recherche des réponses sur Google, j'ai donc pensé ajouter quelque chose d'utile que j'ai trouvé.
Si vous utilisez Visual Studio 2012, il existe un outil intégré qui peut être utilisé pour autoriser un équivalent IDE level "throws").
Si vous utilisez Commentaires sur la documentation XML , comme mentionné ci-dessus, vous pouvez utiliser la balise <exception> pour spécifier le type d'exception levée par la méthode ou la classe ainsi que des informations quand ou pourquoi il est lancé.
exemple:
/// <summary>This method throws an exception.</summary>
/// <param name="myPath">A path to a directory that will be zipped.</param>
/// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
public void FooThrowsAnException (string myPath)
{
// This will throw an IO exception
ZipFile.CreateFromDirectory(myPath);
}
Voici une réponse à une question similaire sur laquelle je viens de financer bytes.com :
La réponse courte est non, il n'y a pas d'exceptions vérifiées en C #. Le concepteur de la langue discute de cette décision dans cette interview:
http://www.artima.com/intv/handcuffs.html
Le plus proche que vous pouvez obtenir est d'utiliser les balises dans votre documentation XML et de distribuer les documents générés par NDoc avec votre code/assemblys afin que d'autres personnes puissent voir quelles exceptions vous lancez (ce qui est exactement ce que MS fait dans la documentation MSDN). Cependant, vous ne pouvez pas compter sur le compilateur pour vous informer des exceptions non gérées, comme vous en avez l'habitude en Java.
Après avoir parcouru la plupart des réponses ici, j'aimerais ajouter quelques réflexions.
S'appuyer sur les commentaires de la documentation XML et s'attendre à ce que les autres comptent sur est un mauvais choix. La plupart du code C # que j'ai rencontré ne documente pas les méthodes de manière complète et cohérente avec les commentaires de la documentation XML. Et puis il y a le plus gros problème: sans les exceptions vérifiées en C #, comment pourriez-vous documenter toutes les exceptions que votre méthode lève pour que votre utilisateur d'API sache comment les gérer individuellement? N'oubliez pas que vous ne connaissez que ceux que vous vous lancez avec le mot clé throw dans votre implémentation. Les API que vous utilisez dans l'implémentation de votre méthode peuvent également générer des exceptions que vous ne connaissez pas car elles peuvent ne pas être documentées et vous ne les gérez pas dans votre implémentation, elles exploseront donc face à l'appelant de votre méthode. En d'autres termes, ces commentaires de documentation XML ne remplacent pas les exceptions vérifiées.
Andreas a lié une interview avec Anders Hejlsberg dans les réponses ici sur les raisons pour lesquelles l'équipe de conception C # a décidé de ne pas vérifier les exceptions. La réponse ultime à la question d'origine est cachée dans cette interview:
Les programmeurs protègent leur code en écrivant des essais finaux partout, donc ils reculeront correctement si une exception se produit, mais ils ne sont pas réellement intéressés par la gestion des exceptions.
En d'autres termes, personne ne devrait être intéressé par le type d'exception à attendre pour une API particulière, car vous allez toujours les attraper partout. Et si vous voulez vraiment vous soucier d'exceptions particulières, la façon de les gérer est à vous et non à quelqu'un de définir une signature de méthode avec quelque chose comme le Java jette le mot-clé, forçant une gestion particulière des exceptions sur une API utilisateur.
-
Personnellement, je suis déchiré ici. Je suis d'accord avec Anders qu'avoir vérifié les exceptions ne résout pas le problème sans ajouter de nouveaux problèmes différents. Tout comme avec les commentaires de la documentation XML, je vois rarement du code C # avec tout ce qui est enveloppé dans des blocs try finally. Il me semble que c'est en effet votre seule option et quelque chose qui semble être une bonne pratique.
Vous posez des questions à ce sujet:
Re-lever une exception
public void Method()
{
try
{
int x = 0;
int sum = 100/x;
}
catch(DivideByZeroException e)
{
throw;
}
}
ou
static void Main()
{
string s = null;
if (s == null)
{
throw new ArgumentNullException();
}
Console.Write("The string s is null"); // not executed
}
En fait, ne pas avoir vérifié les exceptions en C # peut être considéré comme une bonne ou une mauvaise chose.
Je considère moi-même que c'est une bonne solution car les exceptions vérifiées vous posent les problèmes suivants:
Pour cette raison, dans la plupart des applications plus grandes, vous verrez souvent le modèle suivant lorsque les exceptions cochées se produisent:
try {
// Some Code
} catch(SomeException ex){
throw new RuntimeException(ex);
}
Ce qui signifie essentiellement émuler la façon dont C # /. NET gère toutes les exceptions.
Il existe quelques similitudes fugaces entre le .Net CodeContract EnsuresOnThrow<>
et le Java throws
descripteur, en ce que les deux peuvent signaler à l'appelant le type d'exception qui pourrait être levé à partir d'une fonction ou d'une méthode, bien qu'il n'y ait sont également des différences majeures entre les 2:
EnsuresOnThrow<>
va au-delà de la simple indication des exceptions qui peuvent être levées, mais stipule également les conditions dans lesquelles elles sont garanties d'être levées - cela peut être un code assez onéreux dans la méthode appelée si la condition d'exception n'est pas triviale à identifier. Java throws
fournit une indication des exceptions qui pourraient être levées (c'est-à-dire que l'OMI le focus dans .Net est à l'intérieur de la méthode qui se contracte pour prouver le throw
, alors que in Java le focus se déplace vers l'appelant pour reconnaître la possibilité de l'exception)."n'utilisez des postconditions exceptionnelles que pour les exceptions auxquelles un appelant devrait s'attendre dans le cadre de l'API"
throws
pour la même exception sur son interface.