80 votes

Quand utiliser: Tuple vs Class c # 7.0

Avant Tuples, j'avais l'habitude de créer un class et ses variables, puis de créer un objet à partir de cette classe et de faire de cet objet le type de retour pour certaines fonctions.

Maintenant, avec les tuples, je peux faire la même chose et dans c # 7.0, nous pouvons assigner des noms compréhensibles pour les propriétés des tuples (auparavant, c'était item1 , item2 , etc.)

Alors maintenant, je me demande quand devrais-je utiliser des n-uplets et quand devrais-je créer une classe en c # 7.0?

61voto

David Arno Points 15499

Comme cette réponse entraîne une certaine confusion chez certains folklorique ici, je me dois de préciser que, comme pour la question - toutes les références à "tuple" ici se référer à l' ValueTuple type et le nouveau tuple sucre syntaxique fonctionnalités de C# 7 et, en aucune façon, reportez-vous à la vieux - System.Tuple types de référence.

Alors maintenant, je me demande, quand dois-je utiliser les tuples et quand dois-je créer une classe en c# 7.0?

Que vous pouvez vraiment répondre à cette question car cela dépend vraiment de votre code.

Cependant, il existe des lignes directrices et des règles que vous pouvez suivre pour vous guider dans le choix d'entre eux:

Les Tuples sont des valeurs, donc, sont copiés par valeur et non par référence.

La plupart du temps, cela ne devrait pas être un problème. Toutefois, si vous êtes de passage autour de tuples de grandes structures, cela pourrait avoir un impact sur les performances. Ref habitants/retours peuvent être utilisées pour contourner ces problèmes de performances, cependant.

En outre, parce qu'ils sont des valeurs, de la modification d'une copie à distance ne changera pas la copie originale. C'est une bonne chose, mais il pourrait attraper un peu folk.

Tuple les noms d'élément ne sont pas conservées

Les noms donnés à des éléments utilisés par le compilateur et (dans la plupart des cas) ne sont pas disponibles au moment de l'exécution. Cela signifie que la réflexion ne peut pas être utilisé pour découvrir leurs noms; ils ne peuvent pas être accessibles dynamiquement et ils ne peuvent pas être utilisés dans de rasoir points de vue.

Aussi c'est une considération importante avec les Api. Un tuple est retourné à partir d'une méthode est l'exception à la règle relative à l'après-nom de la compilation de détectabilité. Le compilateur ajoute des attributs de la méthode que de détenir des informations sur le tuple noms. Cela signifie que vous pouvez revenir en toute sécurité par un tuple d'une méthode publique dans une assemblée et d'accéder à ses noms dans un autre.

Les Tuples sont légers

Les Tuples sont beaucoup plus simple à écrire que les types comme ils sont moins détaillées et la déclaration peut être "inline" (c'est à dire déclarée au moment de l'utilisation). Cela fonctionne bien lorsque l'on déclare une méthode qui retourne plusieurs valeurs, par exemple.

Cependant, parce qu'ils sont déclarés au moment de l'utilisation, si vous avez MethodA qui appelle MethodB qui appelle MethodC , et chacun retourne un tuple, vous aurez besoin de redéfinir le tuple à chaque étape. Il n'y a pas (encore) une façon de créer un alias d'un n-uplet et de ré-utiliser dans plusieurs méthodes.

Juste du bon sens

Pour toute situation où vous pourriez envisager d'utiliser un tuple: il suffit de vous poser la question: "est un n-uplet de simplifier le code ici". Si la réponse est "oui", puis d'en utiliser un. Et qui est finalement l'essentiel de l'examen sur la question de l'utilisation d'un tuple ou une classe personnalisée.

29voto

Gusdor Points 5872

En général, nommé classes ont une certaine importance dans la conception de votre système. Ils sont également plus verbeux à écrire. Par exemple, vous pouvez avoir une classe appelée MediaFileOpener. Il est important de la conception que nous savons ce que cette classe ne comprend - nous travaillons avec des fichiers multimédia!

Les types anonymes et les tuples sont utilisés lorsqu'il n'y a pas de conception de la signification et tout ce que vous voulez, c'est un léger Transfert de Données Objet (DTO) pour déplacer l'information autour de vous.

En règle générale, si votre classe nécessite un peu de documentation pour décrire ce qu'elle est, ou si il y a des comportements qu'il fournit, l'utilisation d'une classe complète. Si vous avez besoin de stockage temporaire ou une sorte de groupement, l'utilisation d'un n-uplet. Imaginez une situation où vous voulez retourner plus d'une valeur à partir d'une méthode asynchrone. Tuple est conçu pour résoudre ce problème.

11voto

dimlucas Points 3105

Utiliser une Classe

Si vos objets sont des entités qui sont largement utilisés tout au long de votre demande et sont également stockées dans une sorte de stockage persistant comme une base de données relationnelle (SQL Server, MySQL, SQLite), une Base de données NoSQL ou Cache (Redis Azure DocumentDB), ou même sur de simples fichiers texte ou des CSVs.

Donc oui, quelque chose de persistant doit avoir sa propre classe.

Utiliser un Tuple

Si vos objets sont de courte durée sans une signification particulière pour votre application. Par exemple, si vous avez besoin de revenir rapidement une paire de coordonnées, c'est mieux d'avoir quelque chose comme ceci:

(double Latitude, double Longitude) getCoordinates()
{
    return (144.93525, -98.356346);
}

que de définir une classe à part

class Coordinates
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

Un n-uplet, vous gagnerez du temps d'avoir à allouer de la mémoire sur le tas à l'aide de new pour une opération simple.

Une autre fois, quand je trouve des n-uplets est utile lors de l'exécution de plusieurs opérations mathématiques sur certains opérandes

(double Result1, double Result2, double Result3) performCalculations(int operand1, int operand 2)

Il n'est pas judicieux de définir une classe dans ce cas. Peu importe ce que les calculs sont les résultats n'appartiennent pas à une classe. Donc l'alternative serait d'utiliser out variables, mais je crois que les tuples sont plus expressifs et entraîner une amélioration de la lisibilité.

4voto

Theraot Points 5174

Je veux commencer par mentionner que C# déjà eu de soutien pour les types anonymes. Qui sont des types référence. Ainsi, vous aviez déjà une alternative à la création d'une classe nommée.

L'un des avantages d'un nom de classe est la classe sera plus facile de les réutiliser (par exemple, si vous avez besoin du même type dans plusieurs endroits) et document. Depuis le type anonyme, anonyme, vous ne pouvez obtenir des variables typées, si vous pouvez utiliser var, ce qui limite les contextes dans lesquels les types anonymes sont utiles (par exemple, vous ne pouvez pas les utiliser comme des types de champs, types de retour ou des types de paramètres).

Bien sûr, vous pouvez aller sur certains de les limitations des types anonymes en utilisant System.Tuple. Qui est aussi un type de référence, et vous pouvez l'utiliser de manière explicite. L'inconvénient est qu'il manque des noms personnalisés pour les membres.


C# 7 n-uplets (ValueTuple) peuvent être considérés comme similaires aux types anonymes. La première différence est qu'ils sont des types de valeur. Cela signifie que ces n-uplets aura avantage de performance tant qu'ils restent à portée locale ou se déplaçant à travers la pile (qui est l'utilisation commune des types anonymes, en raison de sa limitation).

La deuxième différence est que la nouvelle syntaxe permet aux tuples d'apparaître dans plus d'endroits que les types anonymes, comme vous le savez, vous avez de sucre syntaxique pour définir le type de retour d' ValueTuple (tout en utilisant les types anonymes de retour object).

La troisième différence est que, ValueTuple prend en charge la déconstruction de la boîte. Pour citer les nouveautés de C# 7.0:

Une autre façon de consommer de tuples est à déconstruire. La déconstruction de la déclaration est d'une syntaxe pour la division d'un n-uplet (ou autre valeur) dans ses parties, et l'affectation de ces pièces individuellement frais variables:

(string first, string middle, string last) = LookupName(id1); // deconstructing declaration
WriteLine($"found {first} {last}.");

Que vous pouvez aussi le faire avec des types personnalisés en ajoutant une Déconstruire méthode.


Pour résumé:

  • ValueTuple a sucre syntaxique en C# 7.0, qui doivent être considérées pour des raisons de lisibilité.
  • ValueTuple est un type valeur. Tous les avantages et les inconvénients entre l'utilisation d'un class et struct s'appliquent.
  • ValueTuple peut être utilisé explicitement (avec ou sans sucre syntaxique) lui permettant d'avoir la polyvalence de l' System.Tuple tout en conservant les membres nommés.
  • ValueTuple prend en charge la déconstruction.

Donné, qui doit il est sucre syntaxique, je dirais que le plus fort argument pour choisir ValueTuple est le même argument pour choisir un struct. Ce qui serait idéal pour les petits, immuable types, qui vivent pour la plupart sur la pile (si vous n'avez pas beaucoup de boxing et unboxing).

En comparant ValueTuple contre une véritable structure, considérant le sucre syntaxique, je suggère d'utiliser ValueTuple par défaut, sauf si vous avez besoin d'une disposition explicite ou vous avez besoin d'ajouter des méthodes à elle.

Je tiens aussi à dire que le sucre syntaxique n'est pas nécessairement d'améliorer la lisibilité. La raison principale étant que vous n'êtes pas à nommer le type et le nom du type qui donne un sens à la code. En plus de cela, vous pouvez ajouter de la documentation à un struct ou class déclaration qui facilite la compréhension.

Dans l'ensemble, la situation où l' ValueTuple brille vraiment, c'est de retourner plusieurs valeurs à partir d'une méthode. Dans ce cas, la suppression de la nécessité de créer de nouveaux out paramètres. Et la documentation de l' ValueTuple utilisé peut vivre dans la documentation de la méthode. Si vous trouvez que vous avez besoin de faire autre chose avec l' ValueTuple (définition de méthodes d'extension par exemple), je suggère d'envisager la création d'un type nommé à la place.

2voto

Paulo Morgado Points 1015

Les tuples sont destinés à représenter plusieurs valeurs, comme lorsqu'une méthode a l'intention de renvoyer plusieurs valeurs. La prise en charge des tuples en C # 7 utilise les occurrences System.ValueTuple<...> pour représenter cet ensemble de valeurs. Les noms de ces valeurs ne sont valides que dans le contexte où elles sont utilisées et ne sont pas appliquées.

Les classes sont destinées à représenter une seule valeur avec plusieurs attributs.

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