Discards en het discard-patroon

Tip

Dit artikel maakt deel uit van de sectie Grondbeginselen voor ontwikkelaars die al ten minste één programmeertaal kennen en C# leren. Als u geen gebruik hebt van patronen, begint u met het overzicht van patroonkoppeling. Zie de verwijzing naar het verwijderingspatroon voor volledige syntaxis.

Het onderstrepingstoken (_) communiceert dat een waarde niet nodig is. De exacte betekenis hangt af van waar het wordt weergegeven:

Context Betekenis van _
Een onderdeel van een switch-expressie of een genest patroon Een verwijderingspatroon dat overeenkomt zonder het resultaat vast te leggen
Een deconstructie of out argumentatie Een verwijdering die één geproduceerde waarde negeert
Een opdracht zoals _ = expression Een toewijzing voor verwijderen die de expressie evalueert en het resultaat negeert
Twee of meer lambda-parameters met de naam _ Parameters verwijderen waarvan de invoer niet wordt gebruikt
var _ in een patroon Een var patroon met een verwijderingsaanduiding

Deze formulieren delen spelling en intentie, maar ze zijn niet uitwisselbaar.

Patroonherkenning met switch

In het volgende voorbeeld is statusCode een int. Elke schakelarm produceert een string bericht dat het programma naar de console schrijft. De laatste _ verwerkt elke statuscode anders dan 200 en 404:

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

    Console.WriteLine(message);
}

Er wordt een verwijderingspatroon toegepast op een invoerexpressie. C# evalueert de expressie en _ komt overeen met de geëvalueerde waarde zonder deze vast te leggen. Kies _ als de laatste arm van de switch-expressie wanneer elke waarde die niet eerder is afgehandeld, dezelfde fallback moet gebruiken. Zet het laatst omdat het overeenkomt met alles, inclusief null.

Het formulier var _ is een var patroon met een verwijderingsaanduiding. Het komt ook overeen met elke geëvalueerde waarde, maar er wordt geen leesbare variabele geïntroduceerd. Geef de voorkeur aan het kortere _ verwijderingspatroon voor een switch catch-all. Zie var voor meer informatie over var-patronen en aanduidingen.

Demontageverklaringen

GetForecast retourneert een tuple met vier onderdelen: een string plaats en drie int waarden voor de hoge temperatuur, lage temperatuur en regenkans. De deconstructiedeclaratie behoudt city en high omdat het programma die weergeeft. Het gebruikt _ voor de lage temperatuur en regenkans omdat het benoemen van deze ongebruikte onderdelen impliceert dat de code ze nodig heeft:

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

Dezelfde syntaxis voor verwijderen werkt wanneer de methode van Deconstruct een object verschillende waarden produceert. Zie Deconstructing tuples en andere typen voor deze formulieren.

Aanroepen naar methoden met out parameters

Stel dat een invoerveld alleen tekst accepteert wanneer het een geheel getal vertegenwoordigt. De TryParse(String, Int32) methode retourneert een bool die rapporteert of parseren is geslaagd. Het geeft ook de geparste int terug via de parameter out. De volgende code heeft alleen het Booleaanse resultaat nodig om de invoer te accepteren of af te wijzen:

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

Gebruik out _ wanneer alleen het succes van de bewerking van belang is. De verwijdering maakt duidelijk dat het geparseerde getal niet nodig is. Als latere code het getal nodig heeft, geeft u het out argument een naam op, zoals out int number, en behoudt u die waarde.

Een verwijderingstoewijzing, _ = expressionevalueert een expressie en negeert het resultaat opzettelijk. Soms is dit handig als de expressie anders geen geldig statement is.

Important

Gebruik _ = SomeAsyncMethod() of _ = Task.Run(...) niet om een taak te negeren in toepassingscode. Wacht tot de taak is voltooid en blijven uitzonderingen aanwezig in de aanroepstroom. Een discard-toewijzing maakt een taak niet veiliger, zorgt er niet voor dat de uitzondering ervan wordt waargenomen en creëert geen ondersteunde fire-and-forget-operatie.

Ongebruikte lambda-parameters markeren

Een EventHandler ontvangt een EventArgs afzender en een object? waarde. De volgende handler heeft geen van beide parameters nodig; het schrijft "Timer tick" alleen naar de console. Als u beide parameters _ een naam geeft, wordt de ongebruikte status zichtbaar zonder namen te bedenken die nooit door de hoofdtekst worden gebruikt:

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

Kies verwijderingsparameters wanneer voor een gedelegeerde handtekening invoer is vereist die niet door de lambda-hoofdtekst wordt gebruikt. Als een lambda slechts één parameter heeft met de naam _, _ blijft een gewone parameternaam voor achterwaartse compatibiliteit.

Vermijd _ als identifier

_ kan een gewone id zijn in contexten waarbij C# een verwijdering niet herkent. Een variabele binnen het bereik met de naam _ kan een toewijzing krijgen die op een discard-toewijzing lijkt. In een patrooncontext kan een toegankelijke constante of een benoemd _ type ook wijzigen hoe _ deze wordt geïnterpreteerd. Vermijd het declareren van eigen variabelen, constanten of typen met de naam _; gebruik _ om aan te geven dat je een waarde wilt negeren.

Zie ook