Question

Je me demande simplement comment les autres développeurs traitent ce problème d'obtenir 2 ou 3 réponses d'une méthode.

1) retourner un objet []
2) renvoyer une classe personnalisée
3) utiliser un mot clé out ou ref sur plusieurs variables
4) écrivez ou empruntez (F #) un simple tuple & Lt; & Gt; classe générique
http://slideguitarist.blogspot.com/2008/02/whats- f-tuple.html

Je travaille sur un code qui actualise les données. À partir de la méthode qui effectue l'actualisation, j'aimerais revenir (1) Heure de début d'actualisation et (2) Heure de fin d'actualisation.
Plus tard, je souhaiterai peut-être renvoyer une troisième valeur.

Des pensées? Des bonnes pratiques de projets .NET open source sur ce sujet?

Était-ce utile?

La solution

Votre question indique la possibilité que vous retourniez plus de données à l'avenir. Je vous recommanderais donc d'implémenter votre propre classe pour contenir les données.

Cela signifie que la signature de votre méthode restera la même, même si la représentation interne de l'objet que vous transmettez est modifiée pour prendre en charge davantage de données. C'est également une bonne pratique pour des raisons de lisibilité et d'encapsulation.

Autres conseils

Cela dépend entièrement des résultats. S'ils sont liés les uns aux autres, je créerais généralement une classe personnalisée.

S'ils ne sont pas vraiment liés, j'utilisais un paramètre out ou divisais la méthode. Si une méthode veut renvoyer trois éléments non liés, elle en fait probablement trop. L'exception à cette règle est lorsque vous parlez au-delà d'une limite de service Web ou de quelque chose d'autre où un & "Purer &"; L’API est peut-être trop bavarde.

Pour deux, généralement 4)

Plus que ça, 2)

En ce qui concerne l'architecture de code, je choisirais toujours une classe personnalisée lorsqu'un nombre spécifique de variables a été modifié. Pourquoi? Tout simplement parce qu'une classe est en réalité un & Quotile "plan directeur &"; d’un type de données souvent utilisé, la création de votre propre type de données, en l’occurrence, vous aidera à obtenir une bonne structure et à aider les autres à programmer pour votre interface.

Personnellement, je déteste les param / out, je préfère donc ne pas utiliser cette approche. En outre, la plupart du temps, si vous devez renvoyer plusieurs résultats, vous faites probablement une erreur.

Si cela est vraiment inévitable, vous serez probablement le plus heureux d’écrire une classe personnalisée à long terme. Retourner un tableau est tentant car il est facile et efficace à court terme, mais utiliser une classe vous donne la possibilité de changer le type de retour à l'avenir sans avoir à vous soucier de causer des problèmes en aval. Imaginez la possibilité d’un cauchemar de débogage si une personne échange l’ordre de deux éléments dans le tableau renvoyé ....

J'utilise out s'il ne s'agit que de 1 ou 2 variables supplémentaires (par exemple, une fonction renvoie un résultat booléen, mais également un paramètre long en tant que paramètre indiquant la durée d'exécution de la fonction, à des fins de journalisation) .

Pour tout ce qui est plus compliqué, je crée généralement une structure / classe personnalisée.

Je pense que la méthode la plus courante utilisée par un programmeur C # consiste à envelopper les éléments que vous souhaitez renvoyer dans une classe distincte. Cela vous fournirait le plus de flexibilité possible, IMHO.

Cela dépend. Pour une API interne uniquement, je choisirai généralement l'option la plus simple. Généralement c'est dehors.

Pour une API publique, une classe personnalisée a généralement plus de sens - mais si c'est quelque chose d'assez primitif, ou si le résultat naturel de la fonction est un booléen (comme * .TryParse), je vais m'en tenir à un paramètre out. Vous pouvez également créer une classe personnalisée avec une distribution implicite, mais c'est généralement bizarre.

Dans votre cas particulier, une classe DateRange immuable et simple me semble la plus appropriée. Vous pouvez facilement ajouter cette nouvelle valeur sans déranger les utilisateurs existants.

Si vous souhaitez renvoyer les heures de début et de fin d'actualisation, cela suggère une classe ou une structure possible, appelée éventuellement DataRefreshResults. Si votre troisième valeur possible est également liée à l'actualisation, vous pouvez l'ajouter. Rappelez-vous qu’une structure est toujours passée par valeur, elle est donc allouée sur le tas, il n’a pas besoin d’être récupérée.

Certaines personnes utilisent KeyValuePair pour deux valeurs. Ce n’est pas génial car il ne fait que nommer les deux éléments Key et Value. Pas très descriptif. En outre, il serait très utile d’avoir ajouté ceci:

public static class KeyValuePair
{
    public static KeyValuePair<K, V> Make(K k, V v) 
    { 
        return new KeyValuePair<K, V>(k, v); 
    }
}

vous évite d'avoir à spécifier les types lorsque vous en créez un. Les méthodes génériques peuvent déduire des types, les constructeurs de classes génériques ne peuvent pas.

Pour votre scénario, vous voudrez peut-être définir une classe générique Range {T} (avec des contrôles de validité de la plage).

Si method est privé, j'utilise habituellement des nuplets ma bibliothèque d'assistance . Les méthodes publiques ou protégées méritent généralement toujours d'être séparées.

Renvoyez un type personnalisé, mais n'utilisez pas de classe, utilisez une structure - aucune surcharge mémoire / surcharge pour la récupération de place ne signifie aucun inconvénient.

Si 2, une paire.

Si plus de 2 d'une classe.

Une autre solution consiste à renvoyer un dictionnaire de références d’objets nommés. Pour moi, cela revient à utiliser une classe de retour personnalisée, mais sans encombrement. (Et en utilisant RTTI et la réflexion, il est tout aussi typé que toute autre solution, bien que de manière dynamique.)

Cela dépend du type et de la signification des résultats, ainsi que du caractère privé ou non de la méthode.

Pour les méthodes privées, je n'utilise généralement qu'un tuple de ma bibliothèque de classes.

Pour les méthodes publiques / protégées / internes (c'est-à-dire non privées), j'utilise un paramètre out ou une classe personnalisée.

Par exemple, si j'implémente le modèle TryXYZ, dans lequel vous disposez d'une méthode XYZ qui lève une exception en cas d'échec et d'une méthode TryXYZ qui retourne une valeur booléenne, TryXYZ utilisera un paramètre out.

Si les résultats sont orientés séquence (c.-à-d. qu'ils renvoient 3 clients à traiter), je renverrai généralement une sorte de collection.

Autre que cela, je n'utilise habituellement qu'une classe personnalisée.

Si une méthode génère deux à trois valeurs liées, je les regrouperais dans un type. Si les valeurs ne sont pas liées, la méthode en fait probablement beaucoup trop et je la reformulerais en plusieurs méthodes plus simples.

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