Question

Je ne comprends pas quand un paramètre de sortie doit être utilisé, je conclurai personnellement le résultat dans un nouveau type si je dois revenir plus d'un type, je trouve que beaucoup plus facile à travailler que sur.

Je l'ai vu méthode comme ça,

   public void Do(int arg1, int arg2, out int result)

sont-il des cas où cela fait réellement sens?

Que diriez-vous TryParse, pourquoi ne pas renvoyer un type de ParseResult? ou dans le cadre plus récent retourner un type null-mesure?

Était-ce utile?

La solution

Out est bon quand vous avez une fonction TryNNN et il est clair que le hors-paramètre sera toujours réglée même si la fonction ne réussit pas. Cela vous permet dépendez sur le fait que la variable locale vous déclarez sera mis plutôt que d'avoir à placer des contrôles plus tard dans votre code contre nul. (Un commentaire ci-dessous indique que le paramètre peut être réglé sur null, de sorte que vous pouvez vérifier la documentation de la fonction que vous appelez pour être sûr si tel est le cas ou non.) Il rend le code un peu plus clair et plus facile lire. Un autre cas est quand vous avez besoin de retourner des données et un statut sur la condition de la méthode comme:

public bool DoSomething(int arg1, out string result);

Dans ce cas, le retour peut indiquer si la fonction a réussi et le résultat est stocké dans le paramètre out. Certes, cet exemple est contraint parce que vous pouvez concevoir une manière où la fonction retourne simplement une string, mais vous voyez l'idée.

Un inconvénient est que vous devez déclarer une variable locale pour les utiliser:

string result;
if (DoSomething(5, out result))
    UpdateWithResult(result);

Au lieu de:

UpdateWithResult(DoSomething(5));

Cependant, il peut même ne pas être un inconvénient, cela dépend de la conception que vous allez pour. Dans le cas de DateTime, les deux moyens (analyser et TryParse) sont fournis.

Autres conseils

Bien que la plupart des choses dont il dépend. Regardons les options

  • vous pouvez retourner tout ce que vous voulez que la valeur de retour de la fonction
  • si vous voulez revenir plusieurs valeurs ou la fonction a déjà une valeur de retour, vous pouvez utiliser sur params ou créer un nouveau type composite qui expose toutes ces valeurs que les propriétés

Dans le cas de TryParse, en utilisant une sortie PARAM est efficace - vous ne devez pas créer un nouveau type qui serait 16B des frais généraux (sur 32b machines) ou supporter le coût de perf d'entre eux ayant d'après collecte des ordures l'appel. TryParse pourrait être appelé à partir d'une boucle, par exemple, - donc hors params règle ici
. Pour les fonctions qui ne seraient pas appelés dans une boucle (à savoir la performance n'est pas une préoccupation majeure), de retour d'un seul objet composite pourrait être « plus propre » (subjective du spectateur). Maintenant, avec des types anonymes et typage dynamique, il pourrait devenir encore plus facile.

Note:

  1. params out ont des règles qui doivent être suivies à savoir le compilateur veillera à ce que la fonction n'initialise la valeur avant sa sortie. Donc TryParse doit régler le sortir à une valeur param même si l'opération parse failed
  2. Le modèle TryXXX est un bon exemple de quand utiliser des params - Int32.TryParse a été introduit coz personnes se sont plaintes du coup de perf d'attraper des exceptions à savoir si Parse a échoué. De plus, le plus probable chose que vous feriez en cas Parse réussi, est d'obtenir la valeur analysée - en utilisant un des param signifie que vous ne devez pas faire un autre appel de méthode pour Parse

Je pense à est utile pour les situations où vous devez retourner à la fois une valeur booléenne et une valeur, comme TryParse, mais ce serait bien si le compilateur permettrait quelque chose comme ceci:

bool isValid = int.TryParse("100", out int result = 0);

Sans aucun doute, des paramètres sont destinés à être utilisés lorsque vous avez une méthode qui a besoin de retourner plus d'une valeur, dans l'exemple que vous avez publié:

public void Do(int arg1, int arg2, out int result)

Il ne fait pas beaucoup de sens d'utiliser un paramètre out, puisque vous ne retournerez une valeur, et cette méthode pourrait être mieux utilisée si vous supprimez le paramètre de sortie et mettez une valeur de retour int:

public int Do(int arg1, int arg2)

Il y a de bonnes choses au sujet sur les paramètres:

  1. Paramètres de sortie sont d'abord considérés comme non affectés.
    • Chaque paramètre out doit être définitivement attribuées avant le retour de la méthode, votre code ne compilera pas si vous manquez une mission.

En conclusion, j'essaie essentiellement utiliser des params dans mon API privée pour éviter de créer des types séparés pour envelopper plusieurs valeurs de retour et sur mon API publique, je ne les utiliser que sur les méthodes qui correspondent à la TryParse motif.

ans de retard avec une réponse, je sais. out (et ref aussi) est également très utile si vous ne souhaitez pas que votre méthode n'instancier un nouvel objet pour revenir. Ceci est très utile dans les systèmes de haute performance où vous souhaitez obtenir des performances sous microseconde pour la méthode. instanciation est relativement coûteux vu dans une perspective d'accès à la mémoire.

Création d'un type juste pour le retour des valeurs semble peu pénible pour moi :-) Tout d'abord je vais devoir créer un type de renvoyer la valeur puis dans la méthode d'appel que j'ai affecter la valeur du type retourné à la variable réelle qui en a besoin.

Out paramètres sont simipler à utiliser.

Oui, il est logique. Prenez ceci par exemple.

String strNum = "-1";
Int32 outNum;

if (Int32.TryParse(strNum, out outNum)) {
    // success
}
else {
    // fail
}

Que pourriez-vous revenir si l'opération a échoué dans une fonction normale avec une valeur de retour? Vous certainement ne pouvait pas retourner -1 pour représenter un échec, parce qu'alors il n'y aurait pas de différence entre la valeur fail-retour et la valeur réelle qui a été en cours d'analyse pour commencer. Voilà pourquoi nous revenons une valeur booléenne pour voir si elle a réussi, et si elle a fait alors nous avons notre valeur « retour » en toute sécurité déjà attribué.

Il ne me embêter que je ne peux pas passer nulle au paramètre pour les fonctions TryParse.

, je préfère encore dans certains cas, de retour d'un nouveau type avec deux morceaux de données. Surtout quand ils sont sans rapport avec la plupart du temps ou une seule pièce est nécessaire que pour une seule opération un moment après. Lorsque je dois enregistrer la valeur résultante d'une fonction TryParse Je aime vraiment avoir un paramètre out plutôt que d'une classe ResultAndValue au hasard que je dois traiter.

Si vous créez toujours un type, alors vous pouvez vous retrouver avec beaucoup de désordre dans votre application.

Comme dit ici, un cas d'utilisation typique est une méthode de TrySomething où vous voulez retourner un bool comme un indicateur de la réussite et la valeur réelle. Je trouve aussi que un peu peu plus propre dans une instruction if -. Les trois options ont à peu près le même de toute façon LOC

int myoutvalue;
if(int.TryParse("213",out myoutvalue){
    DoSomethingWith(myoutvalue);
}

vs.

ParseResult<int> myoutvalue = int.TryParse("213");
if ( myoutvalue.Success ) {
    DoSomethingWith(myoutvalue.Value);
}

vs.

int? myoutvalue = int.TryParse("213");
if(myoutvalue.HasValue){
    DoSomethingWith(myoutvalue.Value);
}

Quant à la « Pourquoi ne pas retourner un type Nullable »: TryParse existe depuis 1.x-cadre, alors que nullables types sont venus avec 2,0 (Comme ils ont besoin Generics). Alors, pourquoi la compatibilité de rupture ou commencer à introduire inutilement des incohérences entre TryParse sur certains types? Vous pouvez toujours écrire votre propre méthode d'extension pour dupliquer les fonctionnalités déjà existantes (voir Eric Lipperts Poster sur un sujet sans rapport qui comprend un raisonnement derrière des choses à faire / ne pas faire)

Un autre cas d'utilisation est si vous devez retourner plusieurs valeurs sans rapport, même si si vous que cela devrait déclencher une alarme que votre méthode fait peut-être trop. D'autre part, si votre méthode est quelque chose comme une base de données coûteuse ou un appel de service Web et que vous souhaitez mettre en cache le résultat, il est logique de le faire. Bien sûr, vous pouvez créer un type, mais encore une fois, cela signifie un type plus dans votre application.

J'utilise sur paramètres parfois pour une meilleure lisibilité, lors de la lecture du nom de la méthode est plus important que ce que la sortie de la méthode est, en particulier pour les méthodes qui exécutent des commandes en plus des résultats retour.

StatusInfo a, b, c;

Initialize(out a);
Validate(a, out b);
Process(b, out c);

vs.

StatusInfo a = Initialize();
StatusInfo b = Validate(a);
StatusInfo c = Process(b);

Au moins pour moi, j'ai mis beaucoup d'emphase sur les premiers caractères de chaque ligne quand je numérisation. Je peux facilement dire ce qui se passe dans le premier exemple après avoir reconnu que certaines variables « StatusInfo » sont déclarées. Dans le second exemple, la première chose que je vois est qu'un groupe de StatusInfo est récupéré. Je dois analyser une seconde fois pour voir quel genre d'effets les méthodes peuvent avoir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top