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.