Quand «Try» est-il censé être utilisé dans les noms de méthodes C #?

180

Nous discutions avec nos collègues de ce que cela signifie si le nom de la méthode commence par "Try".

Il y avait les opinions suivantes:

  • Utilisez "Try" lorsque la méthode peut renvoyer une valeur nulle.
  • Utilisez "Try" lorsque la méthode ne lèvera pas d'exception.

Quelle est la définition officielle? Que dit "Try" dans le nom de la méthode? Existe-t-il une directive officielle à ce sujet?

ms007
la source
83
+1 Les gens qui ont beaucoup réfléchi aux noms de leurs fonctions recherchent en fait "le prochain". Je ne sais pas pourquoi cela obtient des votes serrés (et cela vient d'un gars qui en a beaucoup jeté ce soir.)
Jonathon Reinhart
7
@JonathonReinhart, il a obtenu des votes serrés car "Dans sa forme actuelle, cette question ne convient pas à notre format de questions-réponses. Nous nous attendons à ce que les réponses soient étayées par des faits, des références ou une expertise spécifique, mais cette question suscitera probablement des débats, des arguments , sondage ou discussion prolongée. "
Pranav Hosangadi
16
Il y a une déclaration officielle de Microsoft qui répond à la question (voir ma réponse). Comment n'est-ce pas un fait?
Erik Schierboom
6
@PranavHosangadi comme Erik l'a mentionné, il est étayé par des faits. De plus, de nombreux développeurs C # très expérimentés ont une expertise spécifique pour fournir une réponse valide. Bon sang, Eric Lippert est l'architecte en chef du langage C #. Je pense que vous pouvez appeler cela une expertise spécifique .
Jonathon Reinhart
4
@ErikSchierboom Que ce soit la directive MS est un fait. Le fait que la directive MS soit la directive correcte à utiliser est subjectif et discutable.
Servy

Réponses:

148

Ceci est connu sous le nom de modèle TryParse et a été documenté par Microsoft. La page MSDN officielle sur les exceptions et les performances dit :

Considérez le modèle TryParse pour les membres qui peuvent lever des exceptions dans des scénarios courants pour éviter les problèmes de performances liés aux exceptions.

Ainsi, si vous avez du code pour lequel un cas d'utilisation régulier signifierait qu'il pourrait lever une exception (comme l'analyse d'un int), le modèle TryParse a du sens.

Erik Schierboom
la source
2
Un autre lien utile qui documente ce modèle (recherchez TryParse) blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
Vivek Maharajh
2
Fondamentalement, si vous avez une méthode TryParse, vous devez avoir une méthode Parse qui renvoie lorsque TryParse renvoie false. Inversement, si vous avez une méthode Parse, vous devriez envisager d'avoir une méthode TryParse qui renvoie false lorsque Parse lancerait
3Doubloons
5
+1. Pour ajouter à cela, les exceptions concernent généralement des circonstances «exceptionnelles». Si vous faites quelque chose qui pourrait facilement échouer et que cet échec n'est pas particulièrement notable, alors utiliser ce modèle est plus idiomatique qu'un essai / capture
Adam Robinson
Un tel modèle nécessitait-il vraiment des directives de Microsoft? Cela semble assez basique.
Dave Lawrence
19
Ce sont des choses basiques, mais cela ne veut pas dire que les directives ne sont pas utiles. Obtenir de bons éléments de base peut être assez difficile si vous ne connaissez pas suffisamment la plate-forme.
Erik Schierboom
119

(Corrigé) Il existe une ligne directrice officielle, comme l'a suggéré Erik.

Quand je vois la TrySomethingméthode, je l'assume

  • ne jette pas
  • Retour bool
  • si j'attends une valeur, elle est renvoyée via le paramètre 'out'
  • il existe une Somethingméthode qui me permet de gérer toute exception moi-même. (modifier, suggéré par Jesse Webb)
pas jeter
la source
4
Correction - Il a une directive officielle. Voir la réponse d'Erik.
nothrow le
8
+1 Mais j'ai aussi une quatrième attente: s'il y a une TryFoométhode, il y aura une Foométhode similaire qui me permettra de gérer moi-même toute `` exception. Les signatures de ces méthodes seront probablement différentes, de sorte que leurs utilisations ne sont pas interchangeables sans d'autres changements de code.
Jesse Webb
1
@JesseWebb, merci de l'avoir signalé. J'ai ajouté votre commentaire à ma réponse, si cela ne vous dérange pas.
nothrow
1
«Ne jette pas» me semble trop généralisé. Par exemple, Int32.TryParse (String, NumberStyles, IFormatProvider, Int32) lève ArgumentException s'il n'aime pas le paramètre de style.
Jirka Hanika
Je conviens que "ne lance pas" pourrait être considéré comme trop généralisé, mais je crois que l'intention était de transmettre qu'il ne lance pas à la suite de l'exécution plutôt qu'en raison de la valeur des paramètres.
ConfusingBoat
8

Je pense que vous devriez l'utiliser trylorsque vous voulez continuer. Peu importe qu'une méthode renvoie une valeur ou non.

Cas 1: s'il retourne bien, vous pouvez procéder d'une certaine manière.

Cas 2: s'il ne revient pas: ça va toujours; vous pouvez procéder d'une autre manière.

Et si vous attendez une valeur en sortie de cette méthode, utilisez le outparamètre.

Exemple

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}
Ashok Damani
la source
6

Vous devez utiliser "Try" dans le nom de la méthode, lorsque vous voulez manifester le fait que l'invocation de la méthode peut produire un résultat non valide. Selon le standard .NET, ce n'est pas une fonction qui lève une exception, mais la fonction qui renvoie une partie VALIDou NON_VALID, du point de vue du programme, une valeur.

À la fin, tout cela sur la convention de dénomination que vous décidez d'utiliser dans votre groupe.

Tigran
la source
5

Assurez-vous d'inclure trydans votre nom de méthode si:

  • tu ne lances aucune exception
  • votre méthode a la signature suivante: bool TrySomething(input, out yourReturn)

Donc, fondamentalement, si nous utilisons try-methods, nous ne récupérons qu'un résultat booléen.

Ainsi, le code suivant ne lèvera aucune exception:

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

Alors que ce code peut (et dans ce cas sera) lever des exceptions:

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

L'utilisation des méthodes Try est un moyen plus sûr et plus défensif de coder. De plus, l'extrait de code n ° 2 nécessite plus de performances à exécuter s'il ne s'agit pas d'un entier.

Fabian Bigler
la source
Votre extrait de code n ° 2 doit être lu int number = int.Parse(input);si vous souhaitez qu'il soit plus significatif dans ce contexte.
Pierre Arnaud
@PierreArnaud Merci, l'a changé!
Fabian Bigler
Il vous manque toujours la int number;déclaration avant le bloc try et l' number = ...affectation.
Pierre Arnaud
@PierreArnaud Merci, j'ai aussi inclus maintenant 'int number'.
Fabian Bigler
Notez que vous pouvez toujours lancer des exceptions si l'exception est quelque peu indépendante de l'action directe effectuée, comme TryLoadFile(path, out file)woah, en dehors de la RAM. Ainsi, l'appelant ne s'attendrait à aucune erreur pour un mauvais chemin ou un accès refusé, mais une exception pour les choses plus bizarres qui pourraient également mal tourner. Et documentez-le.
Luke Puplett
0

Oncle Bob donne l'exemple ci-dessous dans son livre Clean Code . Chaque fois que nous nous attendons à ce qu'une exception soit levée, nous pouvons utiliser le Trypréfixe d'un nom de méthode:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

Et puis (adapté):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

La tryToShutDownméthode n'effectue aucune gestion des erreurs, car c'est la responsabilité de la sendShutDownméthode.

Le TryParsemodèle de Microsoft enfreint la directive de code propre qui dit que nous devons éviter les paramètres de sortie.

Si nous ne développons pas une nouvelle version de C #, nous n'avons pas à nous en tenir à toutes les directives de Microsoft. Parfois, ils ne sont pas les meilleurs.

Glauber
la source