Wyrażenie dekonstrukcji — wyodrębnianie właściwości pól z krotki lub innego typu zdefiniowanego przez użytkownika

Wyrażenie dekonstrukcji wyodrębnia pola danych z wystąpienia obiektu. Każdy dyskretny element danych jest zapisywany w odrębnej zmiennej, jak pokazano w poniższym przykładzie:

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

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

Powyższy fragment kodu tworzy krotkę zawierającą dwie liczby całkowite, X i Y. Druga instrukcja dekonstrukuje krotkę i przechowuje elementy krotki w oddzielnych zmiennych x i y.

Dokumentacja języka C# zawiera ostatnio wydaną wersję języka C#. Zawiera również początkową dokumentację dla funkcjonalności w publicznych wersjach testowych nadchodzącego wydania języka.

Dokumentacja identyfikuje dowolną funkcję po raz pierwszy wprowadzoną w ostatnich trzech wersjach języka lub w bieżącej publicznej wersji zapoznawczej.

Wskazówka

Aby dowiedzieć się, kiedy funkcja została po raz pierwszy wprowadzona w języku C#, zapoznaj się z artykułem dotyczącym historii wersji języka C#.

Dekonstrukcja krotki

Wszystkie typy krotki obsługują wyrażenia dekonstrukcji. Dekonstrukcja krotki wydobywa wszystkie jej elementy. Jeśli chcesz tylko niektóre elementy krotki, użyj odrzucenia dla nieużywanych składowych krotki, jak pokazano w poniższym przykładzie:

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

W poprzednim przykładzie składowe Y i label są odrzucane. Można określić wiele wartości pominiętych w jednej operacji dekonstrukcji. Można użyć odrzucań dla wszystkich elementów członkowskich krotki. Poniższy przykład jest legalny, chociaż nie jest przydatny:

var (_, _, _) = tuple2;

Dekonstrukcja rekordów

Typy rekordów, które mają podstawowy konstruktor, obsługują dekompozycję dla parametrów pozycyjnych. Kompilator syntetyzuje metodę Deconstruct, która wyodrębnia właściwości syntetyzowane z parametrów pozycyjnych w konstruktorze podstawowym. Metoda Deconstruct kompilatora nie wyodrębnia właściwości zadeklarowanych jako właściwości w typie rekordu.

record pokazany w poniższym kodzie deklaruje dwie właściwości pozycyjne, SquareFeet i Address, wraz z inną właściwością, RealtorNotes:

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

Podczas dekonstrukcji obiektu House wszystkie właściwości pozycyjne i tylko właściwości pozycyjne są dekonstrukcyjne, jak pokazano w poniższym przykładzie:

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

Tego zachowania można użyć, aby określić, które właściwości typów rekordów są częścią metody Deconstruct kompilatora.

Deklarowanie metod Deconstruct

Można dodać obsługę dekonstrukcji do dowolnej klasy, struktury lub zadeklarowanego interfejsu. Zadeklaruj co najmniej jedną Deconstruct metodę w typie lub jako rozszerzenie dla tego typu. Wyrażenie dekonstrukcji wywołuje metodę void Deconstruct(out var p1, ..., out var pn). Metoda Deconstruct może być metodą instancji lub metodą rozszerzenia. Typ każdego parametru w metodzie Deconstruct musi być zgodny z typem odpowiedniego argumentu w wyrażeniu dekonstrukcji. Wyrażenie dekonstrukcji przypisuje wartość każdego argumentu do wartości odpowiedniego parametru out w metodzie Deconstruct. Jeśli wiele metod Deconstruct pasuje do wyrażenia dekonstrukcji, kompilator zgłasza błąd z powodu niejednoznaczności.

Poniższy kod deklaruje strukturę Point3D, która ma dwie metody 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;
    }
}

Pierwsza metoda obsługuje wyrażenia dekonstrukcji, które wyodrębniają wszystkie trzy wartości osi: X, Yi Z. Druga metoda obsługuje dekonstrukcję tylko wartości planarnych: X i Y. Pierwsza metoda ma arność 3; druga ma arność 2.

W poprzedniej sekcji opisaną metodę Deconstruct sintezowaną przez kompilator dla typów record z konstruktorem podstawowym. Możesz zadeklarować więcej metod Deconstruct w typach rekordów. Te metody mogą dodawać inne właściwości, usuwać niektóre właściwości domyślne lub oba te właściwości. Można również zadeklarować Deconstruct zgodną z podpisem syntetyzowanym kompilatora. Jeśli zadeklarowasz taką metodę Deconstruct, kompilator nie zsyntetyzuje tej metody.

Wiele metod Deconstruct jest dozwolonych, o ile kompilator może określić jedną unikatową metodę Deconstruct dla wyrażenia dekonstrukcji. Zazwyczaj wiele metod Deconstruct dla tego samego typu ma różne liczby parametrów. Można również utworzyć wiele metod Deconstruct, które różnią się od typów parametrów. Jednak w wielu przypadkach zbyt wiele metod Deconstruct może powodować niejednoznaczność i mylące wyniki.

Specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz sekcję dekonstrukcji C# Standard.

Zobacz też

  • operatory i wyrażenia języka C#
  • Typy tupli
  • rekordów
  • typy struktury