Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Tip
Cet article fait partie de la section Notions de base pour les développeurs qui connaissent déjà au moins un langage de programmation et apprennent C#. Commencez par la vue d’ensemble des critères correspondants si les modèles sont nouveaux pour vous.
Une déconstruction affecte les parties individuelles d’une valeur ( ses composants ) à plusieurs variables dans une seule opération. Les composants d’un tuple sont ses éléments, exposés par position. Un autre type peut exposer des composants en définissant une méthode Deconstruct.
Les enregistrements positionnels, qui déclarent leurs propriétés en tant que paramètres de type constructeur, se voient générer automatiquement une méthode Deconstruct.
Déconstructer des tuples
Supposons qu’une méthode retourne un tuple avec des données de ville. Vous pouvez lire chaque composant un à la fois :
var cityData = QueryCityData("New York City");
var city = cityData.City;
var population = cityData.Population;
var area = cityData.Area;
Une déstructuration affecte ces composants en une seule étape :
(string city, int population, double area) = QueryCityData("New York City");
Vous pouvez également laisser C# déduire les types de variables :
var (city, population, area) = QueryCityData("New York City");
Une déconstruction peut mélanger les variables existantes, les variables nouvellement déclarées et les rejets dans une affectation :
(city, var population, _) = QueryCityData("New York City");
Choisissez la forme qui facilite la lecture du code. Un seul var avant les parenthèses est souvent la forme implicite la plus claire. Vous pouvez également combiner des types explicites et var entre parenthèses, mais cette forme est généralement plus difficile à analyser. Si vous n’avez besoin que de certaines valeurs, utilisez des valeurs ignorées au lieu d’omettre des positions.
Ignorer les valeurs inutiles à l’aide de variables ignorées
Chaque valeur produite doit correspondre à une position sur le côté gauche de l’affectation. Quand vous n’avez pas besoin d’une ou plusieurs positions, utilisez _ comme valeur à ignorer :
var (_, _, population1960, _, population2010) = QueryPopulationDataForYears(
"New York City", 1960, 2010);
Ici, le tuple retourne le nom de la ville, deux années et deux valeurs de population. La déconstruction conserve uniquement les valeurs de population, car le calcul utilise uniquement ces composants.
Décomposer les types définis par l’utilisateur
Une classe, un struct ou une interface peut prendre en charge la déconstruction en déclarant une méthode Deconstruct. Chaque composant devient un out paramètre, ce qui permet à la méthode d’attribuer une valeur à la variable de l’appelant sans la retourner. Étant donné que chaque composant est retourné par le biais d’un out paramètre, la méthode elle-même retourne void:
public void Deconstruct(out string firstName, out string middleName, out string lastName)
{
firstName = FirstName;
middleName = MiddleName;
lastName = LastName;
}
Vous pouvez ensuite déconstructer une instance directement :
var (firstName, middleName, lastName) = passenger;
Un type peut fournir plusieurs Deconstruct surcharges avec une arité différente ( le nombre de paramètres déclarés par la méthode) afin que les appelants puissent choisir le nombre de out composants à récupérer :
public void Deconstruct(out string firstName, out string lastName)
{
firstName = FirstName;
lastName = LastName;
}
public void Deconstruct(out string firstName, out string middleName, out string lastName)
{
firstName = FirstName;
middleName = MiddleName;
lastName = LastName;
}
public void Deconstruct(out string firstName, out string lastName, out string city, out string state)
{
firstName = FirstName;
lastName = LastName;
city = City;
state = State;
}
Deux surcharges avec le même nombre de out paramètres sont ambiguës. Le compilateur signale une erreur pour l’appel ambigu, donc il faut distinguer les surcharges par arité, non seulement par les types de paramètres.
Les variables ignorées fonctionnent également avec la déconstruction définie par l’utilisateur. Pour plus d’informations sur les rejets en général, consultez Rejets et le modèle de rejet :
var (firstName, _, city, _) = passenger;
Décomposer les enregistrements
Un type positionnel record ou record struct déclare ses propriétés en tant que paramètres sur la déclaration de type elle-même, à la manière d’un constructeur. Le compilateur génère pour vous Deconstruct une méthode, avec out paramètres correspondant à ces paramètres positionnels :
var (city, highTempC, lowTempC) = forecast;
Seuls les paramètres positionnels participent à cette déconstruction générée. Les propriétés supplémentaires que vous déclarez ailleurs dans l’enregistrement ne sont pas ajoutées automatiquement.
Déstructurer les types qui ne vous appartiennent pas
Si vous ne pouvez pas modifier un type, vous pouvez toujours prendre en charge la déconstruction en écrivant une méthode d’extension, une méthode statique qui ajoute une méthode Deconstruct à un type que vous ne possédez pas, comme s’il s’agissait d’un membre de ce type. Après avoir ajouté la méthode, n’importe quelle Uri valeur peut utiliser la syntaxe de déconstruction :
static class UriExtensions
{
public static void Deconstruct(this Uri uri, out string scheme, out string host, out int port)
{
scheme = uri.Scheme;
host = uri.Host;
port = uri.Port;
}
}
La même règle d’ambiguïté s’applique ici : deux méthodes d’extension Deconstruct avec la même arité sont ambiguës. L’ambiguïté peut également survenir entre une méthode d’instance Deconstruct et une méthode d’extension de même arité. Dans les deux cas, le compilateur signale une erreur pour l’appel ambigu.
Deconstruction intégrée sur les types système
Certains types système définissent déjà une méthode Deconstruct, en utilisant le même mécanisme que celui que vous utiliseriez pour vos propres types. Par exemple, System.Collections.Generic.KeyValuePair<TKey,TValue> prend en charge la déconstruction, ce qui rend l’itération de dictionnaire concise :
foreach (var (repo, commitCount) in repoCommitCounts)
{
Console.WriteLine($"{repo} had {commitCount:N0} commits in this snapshot.");
}
Déconstruction et filtrage par motif
Une Deconstruct méthode permet également des motifs positionnels pour ce type. Un modèle positionnel teste et déconstructe une valeur en une seule étape, en utilisant la même syntaxe entre parenthèses qu’une déconstruction : person is ("Alice", 30) correspond à une Person valeur dont les composants déconstructés sont égaux à ces valeurs. Ceci est différent d’un motif de propriété, qui teste directement les propriétés nommées, telles que person is { Name: "Alice", Age: 30 }. Les motifs de propriété sont généralement plus clairs pour les formes d’objet, car les noms de membres expliquent le test. Les modèles positionnels sont les plus forts lorsque l’ordre porte déjà la signification, par exemple avec des tuples ou d’autres petites valeurs ordonnées.