Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wskazówka
Ten artykuł jest częścią sekcji Podstawy dla deweloperów, którzy już znają co najmniej jeden język programowania i uczą się języka C#. Zacznij od omówienia dopasowywania wzorców, jeśli wzorce są dla Ciebie nowe.
Dekonstrukcja przypisuje poszczególne części wartości — jej składniki — do wielu zmiennych w ramach jednej operacji. Składniki krotki to jej elementy, dostępne przez pozycję. Inny typ może uwidaczniać komponenty, definiując metodę Deconstruct.
Rekordy pozycyjne, które deklarują ich właściwości jako parametry podobne do konstruktora, automatycznie otrzymują metodę Deconstruct.
Dekonstrukcja krotek
Załóżmy, że metoda zwraca krotkę z danymi miasta. Każdy komponent można odczytać pojedynczo:
var cityData = QueryCityData("New York City");
var city = cityData.City;
var population = cityData.Population;
var area = cityData.Area;
Destrukturyzacja przypisuje te składniki w jednym kroku:
(string city, int population, double area) = QueryCityData("New York City");
Możesz również pozwolić, aby język C# wywnioskował typy zmiennych:
var (city, population, area) = QueryCityData("New York City");
Dekonstrukcja może mieszać istniejące zmienne, nowo zadeklarowane zmienne i ignorowane elementy w jednym przypisaniu:
(city, var population, _) = QueryCityData("New York City");
Wybierz formę, która sprawia, że kod jest najłatwiejszy do odczytania. Pojedynczy var przed nawiasami jest często najwyraźniejszą formą domyślną. Można również mieszać jawne typy i var wewnątrz nawiasów, ale zwykle jest to trudniejsze do skanowania. Jeśli potrzebujesz tylko niektórych wartości, użyj symboli ignorowanych zamiast pomijania pozycji.
Ignoruj niepotrzebne wartości za pomocą odrzuceń
Każda wygenerowana wartość musi odpowiadać pozycji po lewej stronie przypisania. Jeśli nie potrzebujesz jednej lub większej liczby pozycji, użyj _ jako elementu odrzucanego:
var (_, _, population1960, _, population2010) = QueryPopulationDataForYears(
"New York City", 1960, 2010);
W tym miejscu krotka zwraca nazwę miasta, dwa lata i dwie wartości populacji. Dekonstrukcja zachowuje tylko wartości populacji, ponieważ obliczenie używa tylko tych składników.
Dekonstruuj typy zdefiniowane przez użytkownika
Klasa, struktura lub interfejs może obsługiwać dekonstrukcję przez zadeklarowanie Deconstruct metody. Każdy składnik staje się out parametrem, który umożliwia metodzie przypisanie wartości z powrotem do zmiennej elementu wywołującego bez zwracania go. Ponieważ każdy składnik jest zwracany za pomocą parametru out , sama metoda zwraca wartość void:
public void Deconstruct(out string firstName, out string middleName, out string lastName)
{
firstName = FirstName;
middleName = MiddleName;
lastName = LastName;
}
Następnie można dekonstruować instancję bezpośrednio:
var (firstName, middleName, lastName) = passenger;
Typ może zapewnić wiele Deconstruct przeciążeń o różnej arności — liczbie out parametrów deklarowanych przez metodę — dzięki czemu osoby wywołujące mogą wybrać liczbę składników do pobrania:
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;
}
Dwa przeciążenia o tej samej liczbie parametrów out są niejednoznaczne. Kompilator zgłasza błąd z powodu niejednoznacznego wywołania, dlatego rozróżniaj przeciążenia według liczby argumentów, nie tylko według typów parametrów.
Odrzucenia działają również z dekonstrukcją zdefiniowaną przez użytkownika. Aby uzyskać więcej informacji na temat odrzucanych wartości ogólnie, zobacz Odrzucane wartości i wzorzec odrzucania:
var (firstName, _, city, _) = passenger;
Dekonstruuj rekordy
Rekord pozycyjny record lub record struct deklaruje swoje właściwości jako parametry w samej deklaracji typu, podobnie jak konstruktor. Kompilator generuje metodę Deconstruct z parametrami out pasującymi do tych parametrów pozycyjnych:
var (city, highTempC, lowTempC) = forecast;
Tylko parametry pozycyjne uczestniczą w tej wygenerowanej dekompozycji. Dodatkowe właściwości zadeklarowane w innym miejscu rekordu nie są dodawane automatycznie.
Dekonstruuj typy, których nie posiadasz
Jeśli nie możesz zmodyfikować typu, nadal możesz obsługiwać dekonstrukcję, pisząc metodę rozszerzenia — metodę statyczną, która dodaje metodę Deconstruct do typu, którego nie jesteś właścicielem, tak jakby była elementem członkowskim tego typu. Po dodaniu metody dowolna Uri wartość może użyć składni dekonstrukcji:
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;
}
}
Ta sama reguła niejednoznaczności ma zastosowanie tutaj: dwie metody rozszerzeń Deconstruct o tej samej liczbie parametrów są niejednoznaczne. Niejednoznaczność może również wystąpić między metodą instancji Deconstruct a metodą rozszerzenia o tej samej arności. W obu przypadkach kompilator zgłasza błąd niejednoznacznego wywołania.
Wbudowana dekonstrukcja typów systemowych
Niektóre typy systemowe już definiują metodę Deconstruct, używając tego samego mechanizmu, którego można użyć dla własnych typów. Na przykład System.Collections.Generic.KeyValuePair<TKey,TValue> obsługuje dekonstrukcję, co sprawia, że iteracja słownika jest zwięzła:
foreach (var (repo, commitCount) in repoCommitCounts)
{
Console.WriteLine($"{repo} had {commitCount:N0} commits in this snapshot.");
}
Dekonstrukcja i dopasowywanie wzorców
Deconstruct Pewna metoda umożliwia również wzorce pozycyjne dla tego typu. Wzorzec pozycyjny testuje i dekonstruuje wartość w jednym kroku przy użyciu tej samej składni w nawiasach co dekonstrukcja: person is ("Alice", 30) pasuje do Person, których zdekonstruowane składniki są równe tym wartościom. Różni się to od wzorca właściwości, który testuje bezpośrednio nazwane właściwości, takie jak person is { Name: "Alice", Age: 30 }. Wzorce właściwości są zwykle bardziej czytelne dla kształtów obiektów, ponieważ nazwy składowych wyjaśniają test. Wzorce pozycyjne są najsilniejsze, gdy znaczenie wynika już z kolejności, na przykład w przypadku krotek lub innych małych uporządkowanych wartości.