Des chercheurs danois et suédois en sciences informatiques et systèmes autonomes ont décortiqué la sécurité...
Nvidia se prépare à livrer la plate-forme serveur HGX-2 qui sera capable d'exploiter la puissance de 16 GPU Tesla V100...
L'EMD, une école de commerce située à Marseille ouvre à la prochaine rentrée l'école du numérique...
ValueTuple
.
Vous devez ajouter le package NuGet System.ValueTuple
pour pouvoir l'utiliser sur les plateformes qui n'incluent pas les types.async
et await
qui reposent sur l'interface INotifyCompletion
, et LINQ
qui repose sur IEnumerable‹T›
en sont des exemples.
Toutefois, le mécanisme de remise change à mesure que le .NET dépend de moins en moins de la plateforme.
Le .NET Framework n'est pas toujours émis à la même cadence que le compilateur de langage.
Quand les nouvelles fonctionnalités de langage reposent sur de nouveaux types, ces types sont disponibles sous la forme de packages NuGet au moment de l'émission des fonctionnalités de langage.
à mesure que ces nouveaux types sont ajoutés à l'API .NET Standard et remis dans le cadre du framework, les packages NuGet ne sont plus obligatoires.Tuple
génériques. Ces classes, toutefois, présentaient deux limitations majeures.
Premièrement, les classes Tuple
nommaient leurs propriétés Item1, Item2, etc.
Ces noms ne comportent aucune information sémantique.
L'utilisation de ces types Tuple
ne permet pas de communiquer la signification de chacune de ces propriétés.
Les nouvelles fonctionnalités de langage vous permettent de déclarer et d'utiliser des noms sémantiquement explicites pour les éléments d'un tuple
.Tuple
entraînent des problèmes de performances car elles sont des types référence.
Utiliser un des types Tuple
signifie allouer des objets.
Sur des chemins réactifs, l'allocation de nombreux petits objets peut avoir un impact mesurable sur les performances de votre application.
Par conséquent, la prise en charge du langage pour les tuples tire parti des nouveaux structs ValueTuple
.class
ou un struct
pour fournir plusieurs éléments.
Malheureusement, cela génère un surplus de travail et masque votre intention de conception.
La création d'un struct
ou d'une class
implique la définition d'un type avec des données et un comportement.
Souvent, vous souhaitez simplement stocker plusieurs valeurs dans un objet unique.ValueTuple
appliquent la règle stipulant que vous ne pouvez pas ajouter
de comportement (méthodes) à ces types tuple
. Tous les types ValueTuple
sont des structs mutables.
Chaque champ de membre est un champ public
. Cela les rend très légers.
Toutefois, cela signifie que les tuples ne doivent pas être utilisés quand l'immuabilité est importante.class
et struct
. Examinons ces différences.struct ValueTuple
possède des champs nommés Item1
, Item2
, Item3
, etc...,
similaires aux propriétés définies dans les types Tuple
existants.
Ces noms sont les seuls noms que vous pouvez utiliser pour les tuples sans nom.
Quand vous ne fournissez pas de nom de champ alternatif à un tuple, vous avez créé un tuple sans nom :Item1
, Item2
, Item3
, etc.
Cependant, ils ont également des synonymes pour tous les éléments que vous avez nommés. Vous créez un tuple nommé en spécifiant le nom de chaque élément.
Une méthode consiste à spécifier les noms dans le cadre de l'initialisation du tuple :Item*
lors de la génération de la sortie compilée.
Le langage MSIL (Microsoft Intermediate Language) compilé n'inclut pas les noms que vous avez donnés à ces éléments.TupleElementNamesAttribute
sur la méthode.
Cet attribut contient une propriété de liste TransformNames
qui contient les noms attribués à chacun des éléments du tuple.ValueTuple
afin de comprendre les règles d'affectation des tuples nommés entre eux.explicitFieldOne
et explicitFieldTwo
, et non localVariableOne
et localVariableTwo
:Item1
dont la valeur est 42
, et stringContent
dont la valeur est "The answer to everything"
:Item3
, ToString
ou Rest
.==
et !=
.
Ces opérateurs fonctionnent en comparant, dans l'ordre, chaque membre de l'argument de gauche à chaque membre de l'argument de droite.
Ces comparaisons se court-circuitent.
Elles arrêtent l'évaluation des membres dès qu'une paire n'est pas égale.
Les exemples de code suivants utilisent ==
, mais toutes les règles de comparaison s'appliquent à !=
.
L'exemple de code suivant montre une comparaison d'égalité pour deux paires d'entiers :unnamed
et anonymous
, n'ont pas de noms sémantiques fournis pour les éléments.
Les noms des champs sont Item1
et Item2
.
Les deux dernières variables, named
et differentName
, ont des noms sémantiques fournis pour les éléments.
Ces deux tuples ont des noms différents pour les éléments.Average
.
Pour plus d'informations sur les différences entre ces formules de calcul d'écart-type, consultez un texte de statistiques.
private static
qui retourne le type tuple avec les trois valeurs de Sum
, SumOfSquares
et Count
:var
pour initialiser le résultat de tuple à partir de l'appel de la méthode ComputeSumAndSumOfSquares
.
Vous pouvez également créer trois variables discrètes à l'intérieur de la méthode ComputeSumAndSumOfSquares
.
Le code suivant montre la version finale :Item1, Item2, et Item3
.
Il est recommandé de fournir des noms sémantiques aux éléments de tuples retournés par les méthodes.LINQ
.
Le résultat final est une projection qui contient certaines propriétés des objets sélectionnés, mais pas toutes.object
ou dynamic
comme type du résultat.LINQ
effectuerait une projection incluant uniquement l'ID et le titre. Une méthode retournant une suite de tuples exprime bien cette conception :select
dans la projection
de requête crée un tuple qui a les éléments ID
et Title
.
var
en dehors des parenthèses :var
avec une ou toutes les déclarations de variables à l'intérieur des parenthèses.(var x, y) = MyMethod();
.
L'erreur CS8184 est générée, car x est déclaré à l'intérieur des parenthèses et y a été précédemment déclaré ailleurs.
Deconstruct
qui affectent des valeurs à un nombre quelconque de
variables out
qui représentent les éléments de données qui composent le type. Par exemple, le type Person suivant définit
une méthode Deconstruct
qui déconstruit un objet person
en éléments représentant le prénom et le nom de famille :deconstruct
permet l'attribution à partir d'un objet Person
de deux chaînes
représentant les propriétés FirstName
et LastName
:Deconstruct
peut être une méthode
d'extension qui désassemble les membres de données accessibles d'un objet. L'exemple ci-dessous montre un type Student
, dérivé du type Person
,
et une méthode d'extension qui déconstruit un objet Student
en trois variables, qui représentent les propriétés FirstName
, LastName
et GPA
:Student
a désormais deux méthodes Deconstruct
accessibles : la méthode d'extension déclarée pour les types Student
et le membre du type Person
.
Les deux sont dans la portée et cela permet à un objet Student
d'être déconstruit en deux ou trois variables.
Si vous affectez un étudiant à trois variables, le prénom, le nom de famille et la moyenne pondérée cumulative (GPA) sont tous retournés.
Si vous affectez un étudiant à deux variables, seuls le prénom et le nom de famille sont retournés.Deconstruct
dans une classe ou une hiérarchie de classes. Plusieurs méthodes Deconstruct
ayant
le même nombre de paramètres out
peuvent rapidement entraîner des ambiguïtés. Les appelants peuvent ne pas être en mesure d'appeler facilement la méthode Deconstruct
souhaitée.Deconstruct
pour Person
a deux paramètres de sortie, et la méthode Deconstruct
pour Student
en a trois.Deconstruct
pourrait convertir l'objet Person
p
en un tuple contenant les deux chaînes, mais elle ne s'applique pas dans le contexte des tests d'égalité.class
ou struct
plus détaillée.
Même ainsi, ils sont particulièrement utiles pour les méthodes
utilitaires private
ou internal
.
Créez des types définis par l'utilisateur, des types class
ou struct
, quand vos méthodes publiques retournent une valeur comportant plusieurs éléments.