4 votes

Y a-t-il une raison d'utiliser les paramètres out avec les valeurs de retour des tuple de C# 7 ?

Je viens de regarder une vidéo présentant le les nouvelles fonctionnalités de C# 7 . Entre autres, il introduit la possibilité de retourner un type de tuple (par ex : (int, int) qui, je crois, est juste un sucre syntaxique pour Tuple<int, int> ). Ainsi, si nous avons une méthode qui renvoie plusieurs valeurs, il y a 3 possibilités en C# sur la façon de le faire :

(int first, int second) ReturnTuple()
{
    return (1, 2);
}

int ReturnOutParam(out int second)
{
    second = 2;
    return 1;
}

CustomObject ReturnObject()
{
    return new CustomObject
    {
        First = 1,
        Second = 2
    };
}

Je crois qu'il n'y a pas d'autres moyens de le faire - si oui, veuillez me corriger.

Laquelle de ces trois méthodes est la bonne ? Et dans quels cas peut-on utiliser les deux autres ? À chaque nouvelle version de C#, j'ai l'impression qu'il y a un ou deux patrons de conception qui sont devenus obsolètes dans le monde .NET. Certaines fonctionnalités étaient très utiles (comme les génériques, les partiels, LINQ, les lambdas, async/await ou le propagateur de nullité). D'autres sont très situationnelles (dynamique, nameof). Et puis il y a celles qui n'ont tout simplement pas de sens pour moi (auto-initialiseurs de propriétés, valeurs de retour de tuple ou fonctions locales).

10voto

Lucas Trzesniewski Points 28646

Tout d'abord, un tuple comme (int, int) est un sucre syntaxique pour ValueTuple<int, int> . Les différences entre Tuple y ValueTuple sont :

  • ValueTuple est un type de valeur, il n'est donc pas nécessaire d'allouer un objet sur le tas.
  • ValueTuple est mutable
  • ValueTuple a (évidemment) un support de langue intégré, et il vous permet de nommer les éléments du tuple par un attribut personnalisé ( TupleElementNamesAttribute ). Avec Tuple vous obtiendrez seulement Item1 , Item2 etc.

Avec chaque nouvelle version de la langue, certaines fonctionnalités deviennent obsolètes. Par exemple, le delegate { } a été remplacée par les lambdas. On pourrait dire que out Les paramètres entrent dans cette catégorie, mais c'est subjectif. Pourtant, toutes les fonctionnalités doivent rester là pour assurer la rétrocompatibilité.

Par exemple, bool int.TryParse(string input, out int value) aurait dû devenir int? int.TryParse(string input) avec l'inclusion des types de valeurs nullables dans le langage, mais l'ancienne fonction était déjà présente dans le cadre, elle devait donc rester.

Ma règle d'or est la suivante : utilisez des tuples de valeur pour les méthodes privées ou les fonctions utilitaires, mais préférez les structures à part entière pour toute API publique, c'est plus propre de cette façon. J'évite généralement out params sauf occasionnellement pour les méthodes privées.

Je ne comprends pas pourquoi certaines de ces nouvelles fonctionnalités n'ont pas de sens pour vous :

  • Les auto-initialisateurs de propriétés sont enfin En fait, ils auraient dû être implémentés en même temps que les propriétés automatiques, mais ont probablement été ignorés en raison de contraintes de temps. C'est un gain évident pour la lisibilité du code, et cela ajoute une fonctionnalité qui a toujours été présente pour les champs.
  • Les valeurs de retour des tuple sont le sujet de votre question, c'est aussi un gain de lisibilité évident par rapport aux anciens tuples. La possibilité de nommer les éléments d'un tuple parle d'elle-même.
  • Les fonctions locales s'avéreront surtout utiles pour mettre en œuvre le modèle d'itérateur, mais j'ai parfois souhaité disposer d'une telle fonctionnalité et je l'ai contournée en utilisant un lambda.

8voto

Adassko Points 3137

Pour moi, cela dépend toujours de la situation. Par exemple pour TryParse c'est quand même plus lisible à faire :

if (int.TryParse("123", out var i))
{
   // i
}

que

var (success, i) = int.TryParse("123");
if (success)
{
   // i
}

et dans la plupart des cas, le fait de renvoyer plus d'une valeur à partir d'une méthode est une odeur de code. Vous devriez toujours envelopper ce que vous retournez dans une classe qui décrit vos valeurs mieux que les classes First y Second .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X