Expresión de deconstrucción - Extraiga propiedades de campos de una tupla u otro tipo definido por el usuario

Una expresión de deconstrucción extrae campos de datos de una instancia de un objeto. Cada elemento de datos discreto se escribe en una variable distinta, como se muestra en el ejemplo siguiente:

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

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

El fragmento de código anterior crea una tupla que tiene dos valores enteros, X y Y. La segunda instrucción deconstruye la tupla y almacena los elementos de tupla en variables x independientes y y.

La documentación de referencia del lenguaje C# cubre la versión más reciente publicada del lenguaje C#. También contiene documentación inicial sobre las características de las versiones preliminares públicas de la próxima versión del lenguaje.

La documentación identifica cualquier característica introducida por primera vez en las últimas tres versiones del idioma o en las versiones preliminares públicas actuales.

Sugerencia

Para buscar cuándo se introdujo por primera vez una característica en C#, consulte el artículo sobre el historial de versiones del lenguaje C#.

Descomposición de tupla

Todos los tipos de tupla admiten expresiones de desestructuración. La deconstrucción de las tuplas extrae todos los elementos de la tupla. Si solo desea algunos de los elementos de tupla, use un descarte para los miembros de tupla sin usar, como se muestra en el ejemplo siguiente:

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

En el ejemplo anterior, se descartan los miembros Y y label. Puede especificar múltiples elementos a descartar en la misma expresión de deconstrucción. Puede usar descartes para todos los miembros de la tupla. El ejemplo siguiente es legal, aunque no resulta útil:

var (_, _, _) = tuple2;

Deconstrucción de registros

Los tipos Record que tienen un compilador principal admiten la deconstrucción para parámetros posicionales. El compilador sintetiza un método Deconstruct que extrae las propiedades sintetizadas a partir de parámetros posicionales en el constructor principal. El método Deconstruct sintetizado por el compilador no extrae propiedades declaradas como propiedades en el tipo de registro.

El record que se muestra en el código siguiente declara dos propiedades posicionales, SquareFeet y Address, junto con otra propiedad, RealtorNotes:

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

Al deconstruir un objeto House, todas las propiedades posicionales y solo las propiedades posicionales, se deconstruen, como se muestra en el ejemplo siguiente:

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);

Puede usar este comportamiento para especificar qué propiedades de los tipos de registro forman parte del método Deconstruct sintetizado por el compilador.

Declaración de métodos Deconstruct

Puede agregar compatibilidad de deconstrucción a cualquier clase, estructura o interfaz que declare. Declare uno o varios Deconstruct métodos en el tipo o como extensión en ese tipo. Una expresión de deconstrucción llama a un método void Deconstruct(out var p1, ..., out var pn). El método Deconstruct puede ser un método de instancia o un método de extensión. El tipo de cada parámetro del método Deconstruct debe coincidir con el tipo del argumento correspondiente en la expresión de deconstrucción. La expresión de deconstrucción asigna el valor de cada argumento al valor del parámetro out correspondiente en el método Deconstruct. Si varios métodos Deconstruct coinciden con la expresión de deconstrucción, el compilador informa un error debido a la ambigüedad.

El código siguiente declara una estructura Point3D que tiene dos 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;
    }
}

El primer método admite expresiones de deconstrucción que extraen los tres valores del eje: X, Yy Z. El segundo método admite la deconstrucción solo de los valores planar: X y Y. El primer método tiene una aridad de 3; el segundo tiene una aridad de 2.

En la sección anterior se describió el método compilador-sintetizado Deconstruct para tipos record con un constructor principal. Puede declarar más métodos Deconstruct en tipos de registro. Estos métodos pueden agregar otras propiedades, quitar algunas de las propiedades predeterminadas o ambas. También puede declarar un Deconstruct que coincida con la firma sintetizada por el compilador. Si declara este tipo de método Deconstruct, el compilador no sintetiza uno.

Se permiten varios métodos Deconstruct siempre que el compilador pueda determinar un método único Deconstruct para una expresión de deconstrucción. Normalmente, varios métodos de Deconstruct para el mismo tipo tienen diferentes números de parámetros. También puede crear varios métodos Deconstruct que difieren según los tipos de parámetro. Sin embargo, en muchos casos, demasiados métodos Deconstruct pueden provocar errores de ambigüedad y resultados engañosos.

Especificación del lenguaje C#

Para más información, consulte la sección de deconstrucción del Estándar C#.

Consulte también