Odrzucenia i wzorzec odrzucenia

Porada

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#. Jeśli dopiero zaczynasz pracę z wzorcami, zacznij od omówienia dopasowania wzorca. Pełną składnię można znaleźć w dokumentacji wzorca odrzucania.

Token podkreślenia (_) informuje, że wartość nie jest potrzebna. Jego dokładne znaczenie zależy od tego, gdzie się pojawia:

Context Znaczenie _
Ramię wyrażenia przełącznika lub zagnieżdżony wzorzec Wzorzec odrzucenia zgodny bez przechwytywania wyniku
Dekonstrukcja lub out argument Odrzucenie, które ignoruje jedną wygenerowaną wartość
Przypisanie, takie jak _ = expression Przypisanie odrzucenia, które oblicza wyrażenie i ignoruje jego wynik
Dwa lub więcej parametrów lambda o nazwie _ Odrzuć parametry, których wartości wejściowe nie są używane
var _ w wzorcu var Wzorzec z oznaczeniem odrzucenia

Te formularze współdzielą pisownię i intencję, ale nie są one wymienne.

Dopasowywanie wzorca za pomocą polecenia switch

W poniższym przykładzie statusCode jest to int. Każde ramię przełącznika generuje komunikat string, który program wypisuje na konsolę. _ Finalnie obsługuje każdy kod stanu inny niż 200 i 404:

static void ShowStatus()
{
    int statusCode = 503;
    string message = statusCode switch
    {
        200 => "Ready",
        404 => "Not found",
        _ => "Another status"
    };

    Console.WriteLine(message);
}

Wzorzec odrzucenia jest stosowany do wyrażenia wejściowego. Język C# oblicza wyrażenie, a _ dopasowuje się do obliczonej wartości bez jej przechwytywania. Wybierz _ jako ostatnie ramię wyrażenia switch, gdy każda wcześniej nieobsłużona wartość powinna używać tej samej domyślnej opcji. Umieść go jako ostatni, ponieważ pasuje do wszystkich elementów, w tym null.

Formularz var _ jest wzorcem var z oznaczeniem odrzucenia. Pasuje również do każdej obliczonej wartości, ale nie wprowadza zmiennej czytelnej. Preferuj krótszy _ wzorzec odrzucenia dla przełącznika catch-all. Aby uzyskać więcej informacji na temat var wzorców i oznaczeń, zobacz Deklaracje, stałe i var wzorce.

Deklaracje dekonstrukcji

GetForecast zwraca krotkę z czterema elementami: string z miastem oraz trzema wartościami int oznaczającymi wysoką temperaturę, niską temperaturę oraz prawdopodobieństwo deszczu. Deklaracja dekonstrukcji zachowuje city i high, ponieważ program je wyświetla. Używa _ dla niskiej temperatury i prawdopodobieństwa deszczu, ponieważ nazwanie tych nieużywanych komponentów sugerowałoby, że kod ich wymaga:

static void ShowForecast()
{
    var (city, high, _, _) = GetForecast();
    Console.WriteLine($"{city}: high {high}°C");

    static (string City, int High, int Low, int RainChance) GetForecast() =>
        ("Portland", 18, 9, 40);
}

Ta sama składnia odrzucania działa, gdy metoda obiektu Deconstruct generuje kilka wartości. W przypadku tych postaci zobacz temat Dekonstrukcja krotek i innych typów.

Wywołania metod z parametrami out

Załóżmy, że pole wejściowe akceptuje tekst tylko wtedy, gdy reprezentuje liczbę całkowitą. Metoda TryParse(String, Int32) zwraca wartość bool , która zgłasza, czy analizowanie zakończyło się pomyślnie. Generuje również przetworzony int za pośrednictwem parametru out. Poniższy kod wymaga tylko wyniku logicznego, aby zaakceptować lub odrzucić dane wejściowe:

static void CheckInput()
{
    string text = "42";

    if (IsWholeNumber(text))
    {
        Console.WriteLine($"Accepted: {text}");
    }
    else
    {
        Console.WriteLine("Enter a whole number.");
    }

    static bool IsWholeNumber(string text) => int.TryParse(text, out _);
}

Użyj out _ , gdy ma znaczenie tylko powodzenie operacji. Odrzucenie jasno pokazuje, że przeanalizowana liczba nie jest potrzebna. Jeśli później kod wymaga numeru, nadaj out argumentowi nazwę, taką jak out int number, i zachowaj tę wartość.

Przypisanie odrzucenia, _ = expression, oblicza wyrażenie i celowo ignoruje jego wynik. Bywa to przydatne, gdy wyrażenie w przeciwnym razie nie jest poprawną instrukcją.

Important

Nie używaj _ = Task.Run(...) ani _ = SomeAsyncMethod() nie odrzucaj zadania w kodzie aplikacji. Poczekaj na zadanie, aby jego ukończenie i wyjątki pozostały w przepływie wywołującym. Przypisanie do odrzucenia nie sprawia, że zadanie staje się bezpieczne, nie powoduje obserwowania jego wyjątku ani nie tworzy obsługiwanej operacji typu „fire-and-forget”.

Oznacz nieużywane parametry lambda

Element EventHandler otrzymuje nadawcę object? i wartość EventArgs. Poniższa procedura obsługi nie wymaga żadnego z tych parametrów; wypisuje tylko "Timer tick" w konsoli. Nazewnictwo obu parametrów _ sprawia, że ich nieużywany stan jest widoczny bez wymyślania nazw, których treść nigdy nie używa:

static void ShowLambdaDiscards()
{
    EventHandler handler = (_, _) => Console.WriteLine("Timer tick");
    handler(null, EventArgs.Empty);
}

Wybierz opcję Odrzuć parametry, gdy sygnatura delegata wymaga parametrów wejściowych, których ciało wyrażenia lambda nie używa. Jeśli parametr lambda ma tylko jeden parametr o nazwie _, _ pozostaje zwykłą nazwą parametru w celu zapewnienia zgodności z poprzednimi wersjami.

Unikaj _ jako identyfikatora

_ może być zwykłym identyfikatorem w kontekstach, w których język C# nie rozpoznaje odrzucenia. Zmienna w zakresie o nazwie _ może odbierać przypisanie, które wygląda jak przypisanie odrzucenia. W kontekście wzorca dostępna stała lub typ o nazwie _ może również wpłynąć na interpretację elementu _. Unikaj deklarowania własnych zmiennych, stałych lub typów o nazwie _; użyj polecenia _ , aby przekazać intencję odrzucenia.

Zobacz też