web-dev-qa-db-fra.com

Pourquoi toutes les surcharges TryParse ont-elles un paramètre de sortie?

J'ai découvert que plusieurs fois, je n'ai pas besoin du paramètre out de la méthode TryParse, mais le problème est que c'est nécessairement. Ici, je vais montrer un exemple quand il n'est pas nécessaire.

Je veux vérifier si une chaîne est un entier, si c'est un entier, puis afficher "Un entier"; sinon, affichez "Pas un entier". Voici donc le code:

string value = Console.ReadLine(); //Get a value from the user.
int num; //Why should I have it?? No need at all !

if (int.TryParse(value, out num))
{
    Console.WriteLine("An integer");
}
else
{
    Console.WriteLine("Not an integer");
}

Je me demande simplement pourquoi TryParse renvoie toujours un paramètre out? Pourquoi il n'a pas la surcharge sans paramètre out?

36
Misha Zaslavsky

Réponse mise à jour:

Dans les versions plus récentes de C #, vous pouvez déclarer le paramètre de sortie en ligne, ce qui vous permet de supprimer la ligne de code dont vous ne voulez pas dans votre exemple:

string value = Console.ReadLine(); //Get a value from the user.

if (int.TryParse(value, out int num))
{
    Console.WriteLine("An integer");
}
else
{
    Console.WriteLine("Not an integer");
}

Vous pouvez simplement ignorer le résultat dans votre code et ne plus avoir cette ligne supplémentaire. Vous avez toujours le paramètre supplémentaire, mais alors?

Le "pourquoi" sous-jacent est toujours le même et ne changera probablement jamais. La méthode devait retourner deux choses, un bool indiquant le succès et un int indiquant la valeur résultante en cas de succès. (Je ne peux pas penser à une autre façon de transmettre le résultat, pouvez-vous?) Puisqu'une méthode ne peut renvoyer qu'une chose et qu'un type de résultat personnalisé semble exagéré pour cela, la décision a été prise de renvoyer le bool et que le résultat soit un paramètre out. Et une fois que cette décision a été prise, elle doit rester pour la durée de la langue.

"Ils" certainement pourraient ajouter une surcharge qui ne sort pas dans la valeur int. Mais pourquoi? Pourquoi investir l'effort dans la conception, la documentation, les tests et, comme nous l'avons vu perpétuellement , soutenir une méthode qui ne sert à rien, mais pour économiser quelques touches pour une extrême minorité de développeurs? Encore une fois, très peu probable.

Pour de telles fonctionnalités, vous êtes certainement invités à proposer un changement . Ce serait plutôt cool d'avoir une proposition acceptée, j'imagine. Je doute que ce soit le cas, mais si vous êtes passionné par cela, alors allez-y.


Réponse originale:

La réponse courte est: "Parce que c'est ainsi que la méthode est définie". Peut-être que par hasard, quelqu'un de l'équipe du langage C # pourrait trouver cette question et expliquer pourquoi pourquoi des décisions ont été prises, mais cela ne change pas grand-chose point. C # est un langage compilé statiquement et les signatures de méthode doivent correspondre, donc c'est exactement comme ça.

(Imaginez s'ils changeaient cela et cassaient .TryParse() sur toutes les bases de code existantes. Ce serait ... mauvais.)

Vous pourrez peut-être contourner cela dans votre propre code, cependant. Quelque chose d'aussi simple qu'une méthode d'extension pourrait faire l'affaire pour vous:

public static bool IsInt(this string s)
{
    int x = 0;
    return int.TryParse(s, out x);
}

Ensuite, dans votre code, il vous suffit d'appeler cette méthode à partir de la valeur de chaîne:

string value = Console.ReadLine();
if (value.IsInt())
    Console.WriteLine("An integer");
else
    Console.WriteLine("Not an integer");
31
David

Il a le paramètre out parce que la grande majorité du temps lorsque les gens l'utilisent, ils veulent l'int (ou double, ou décimal, ou datetime, ou autre) qui a été analysé.

Si vous ne voulez pas/n'avez pas besoin de la valeur analysée, et que vous vous retrouvez à le faire tout le temps, vous pouvez écrire votre propre "wrapper" sur .TryParse() qui ne prend que la chaîne.

Dans cet exemple (et vous pourriez le rendre plus générique, je suis sûr), vous pourriez faire quelque chose comme

public static bool TryParseNoOutput(this string value)
{
  int noNeed = 0;
  return int.TryParse(value, out noNeed);
}

Ensuite, dans votre code (dans ce cas), vous appelez:

string value = Console.ReadLine();
if(value.TryParseNoOutput()) Console.WriteLine("An Integer");
else Console.WriteLine("Not an integer."):

Éditer: Comme cela a été souligné dans les commentaires, j'ai essayé d'appeler "int.TryParseNoOutput" alors que je l'avais défini comme une extension sur une chaîne. La réponse a été mise à jour pour refléter cela.

7
AllenG

TryParse est une opération relativement complexe pour déterminer la représentation int d'un string. S'il y avait une surcharge qui renvoie simplement un bool, il serait très probable que de nombreux développeurs (non expérimentés) suivraient ce modèle inefficace:

int myInt = -1;
if(int.TryParse("123"))
    myInt = int.Parse("123");
5
Tim Schmelter

Pourquoi TryParse a-t-il un paramètre out?
Pour la raison très simple de la mise en œuvre de TryParse.
La façon dont vous déterminez si quelque chose est analysable ou non, c'est en l'analysant! Si vous êtes capable d'analyser quelque chose, alors c'est analysable. Si vous ne pouvez pas l'analyser, il n'est pas analysable.

Par conséquent, pour déterminer si quelque chose est analysable ou non, si elle est analysable, alors nous l'avons déjà analysé! Il serait stupide de jeter cette valeur analysée (toute personne qui se demande si quelque chose est analysable est probablement intéressée par le résultat analysé), donc la valeur analysée est retournée.

Il a un paramètre out car la valeur analysée est un sous-produit d'un appel TryParse à retour vrai.

3
Task