Compartilhar via


Expressão de desconstrução - Extrair propriedades de campos de uma tupla ou outro tipo definido pelo usuário

Uma expressão de desconstrução extrai campos de dados de uma instância de um objeto. Cada elemento de dados discreto é gravado em uma variável distinta, conforme mostrado no exemplo a seguir:

var tuple = (X: 1, Y: 2);
var (x, y) = tuple;

Console.WriteLine(x); // output: 1
Console.WriteLine(y); // output: 2

O snippet de código anterior cria uma tupla que tem dois valores inteiros, X e Y. A segunda instrução desconstrui que tupla e armazena os elementos de tupla em variáveis separadas x e y.

A linguagem C# faz referência a documentos da versão mais recentemente lançada da linguagem C#. Ele também contém a documentação inicial para funcionalidades em pré-visualizações públicas para o próximo lançamento do idioma.

A documentação identifica qualquer recurso introduzido pela primeira vez nas três últimas versões do idioma ou nas versões prévias públicas atuais.

Dica

Para descobrir quando um recurso foi introduzido pela primeira vez em C#, consulte o artigo sobre o histórico de versão da linguagem C#.

Desconstrução de tupla

Todos os tipos de tupla dão suporte a expressões de desconstrução. A desconstrução de tupla extrai todos os elementos da tupla. Se você quiser apenas alguns dos elementos de tupla, use um descarte para os membros de tupla não utilizados, conforme mostrado no exemplo a seguir:

var tuple2 = (X: 0, Y: 1, Label: "The origin");
var (x2, _, _) = tuple2;

No exemplo anterior, os membros Y e label são descartados. Você pode especificar vários descartes na mesma expressão de desconstrução. Você pode descartar todos os membros da tupla. O exemplo a seguir é legal, embora não seja útil:

var (_, _, _) = tuple2;

Desconstrução de registro

Tipos de de registro que têm um construtor primário dão suporte à desconstrução para parâmetros posicionais. O compilador sintetiza um método Deconstruct que extrai as propriedades sintetizadas de parâmetros posicionais no construtor primário. O método Deconstruct sintetizado pelo compilador não extrai propriedades declaradas como propriedades no tipo de registro.

O record mostrado no código a seguir declara duas propriedades posicionais, SquareFeet e Address, juntamente com outra propriedade, RealtorNotes:

public record House(int SquareFeet, string Address)
{
    public required string RealtorNotes { get; set; }
}

Quando você desconstrui um objeto House, todas as propriedades posicionais e apenas propriedades posicionais são desconstruídas, conforme mostrado no exemplo a seguir:

var house = new House(1000, "123 Coder St.")
{
    RealtorNotes = """
    This is a great starter home, with a separate room that's a great home office setup.
    """
};

var (squareFeet, address) = house;
Console.WriteLine(squareFeet); // output: 1000
Console.WriteLine(address); // output: 123 Coder St.
Console.WriteLine(house.RealtorNotes);

Você pode usar esse comportamento para especificar quais propriedades dos tipos de registro fazem parte do método Deconstruct sintetizado pelo compilador.

Declarar métodos Deconstruct

Você pode adicionar suporte à desconstrução a qualquer classe, struct ou interface declarada. Declare um ou mais Deconstruct métodos em seu tipo ou como extensão nesse tipo. Uma expressão de desconstrução chama um método void Deconstruct(out var p1, ..., out var pn). O método Deconstruct pode ser um método de instância ou um método de extensão. O tipo de cada parâmetro no método Deconstruct deve corresponder ao tipo do argumento correspondente na expressão de desconstrução. A expressão de desconstrução atribui o valor de cada argumento ao valor do parâmetro out correspondente no método Deconstruct. Se vários métodos Deconstruct corresponderem à expressão de desconstrução, o compilador relatará um erro devido à ambiguidade.

O código a seguir declara um struct Point3D que tem dois métodos Deconstruct:

public struct Point3D
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }

    public void Deconstruct(out int x, out int y, out int z)
    {
        x = X;
        y = Y;
        z = Z;
    }

    public void Deconstruct(out int x, out int y)
    {
        x = X;
        y = Y;
    }
}

O primeiro método dá suporte a expressões de desconstrução que extraem todos os três valores de eixo: X, Ye Z. O segundo método dá suporte à desconstrução apenas dos valores planares: X e Y. O primeiro método tem uma aridade de 3; o segundo tem uma aridade de 2.

A seção anterior descreveu o método Deconstruct sintetizado pelo compilador para tipos de record com um construtor primário. Você pode declarar mais métodos Deconstruct em tipos de registro. Esses métodos podem adicionar outras propriedades, remover algumas das propriedades padrão ou ambas. Você também pode declarar um Deconstruct que corresponda à assinatura sintetizada pelo compilador. Se você declarar esse método Deconstruct, o compilador não sintetizará um.

Vários métodos Deconstruct são permitidos desde que o compilador possa determinar um método de Deconstruct exclusivo para uma expressão de desconstrução. Normalmente, vários métodos de Deconstruct para o mesmo tipo têm diferentes números de parâmetros. Você também pode criar vários métodos de Deconstruct que diferem por tipos de parâmetro. No entanto, em muitos casos, um excesso de métodos Deconstruct pode levar a erros de ambiguidade e resultados enganosos.

Especificação da linguagem C#

Para obter mais informações, consulte a seção de desconstrução do C# Standard.

Consulte também