Kasseringar och kasseringsmönstret

Tip

Den här artikeln är en del av avsnittet Grunderna för utvecklare som redan känner till minst ett programmeringsspråk och lär sig C#. Om du är nybörjare på mönster börjar du med översikten över mönstermatchning. Fullständig syntax finns i referensen för discard-mönster.

Understreckstoken (_) meddelar att ett värde inte behövs. Den exakta innebörden beror på var den visas:

Context Innebörden av _
En switch-uttrycksarm eller ett kapslat mönster Ett kasseringsmönster som matchar utan att fånga resultatet
En dekonstruktion eller out ett argument En ignorering som ignorerar ett genererat värde
En tilldelning, till exempel _ = expression En kasseringstilldelning som utvärderar uttrycket och ignorerar resultatet
Två eller flera lambda-parametrar med namnet _ Ignorera parametrar vars indata inte används
var _ i ett mönster Ett var mönster med en diskardbeteckning

Dessa formulär delar stavning och avsikt, men de är inte utbytbara.

Mönstermatchning med switch

I följande exempel är statusCode en int. Varje växelarm skapar ett string meddelande som programmet skriver till konsolen. Den sista _ hanterar alla andra statuskoder än 200 och 404:

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

    Console.WriteLine(message);
}

Ett ignorerandemönster tillämpas på ett indatauttryck. C# utvärderar uttrycket och _ matchar det utvärderade värdet utan att samla in det. Välj _ som den sista armen i switch-uttrycket när alla värden som inte har hanterats tidigare ska använda samma reservalternativ. Lägg det sist eftersom det matchar allt, inklusive null.

Formen var _ är ett var-mönster med en ignoreringsbeteckning. Det matchar också varje utvärderat värde, men det introducerar inte en läsbar variabel. Använd det kortare _ discard-mönstret för ett switch-standardfall. Mer information om var mönster och beteckningar finns i Förklaring, konstant och var mönster.

Deklarationer för demontering

GetForecast returnerar en tuppeln med fyra komponenter: en string stad och tre int värden för hög temperatur, låg temperatur och regnchans. Dekonstruktionsdeklarationen behåller city och high eftersom programmet visar dem. Den använder _ för låg temperatur och risk för regn eftersom att namnge de oanvända komponenterna skulle antyda att koden behöver dem:

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

Samma ignorerande syntax fungerar när ett objekts Deconstruct -metod genererar flera värden. De formerna finns i Demontering av tupler och andra typer.

Anrop till metoder med out parametrar

Anta att ett indatafält endast accepterar text när det representerar ett heltal. Metoden TryParse(String, Int32) returnerar en bool som rapporterar om parsningen lyckades. Den genererar också det tolkade int via parametern out. Följande kod behöver bara det booleska resultatet för att acceptera eller avvisa indata:

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

Använd out _ när endast åtgärdens framgång är viktig. Ignorera gör det tydligt att det parsade talet inte behövs. Om senare kod behöver talet ger du out argumentet ett namn, till exempel out int number, och behåller det värdet i stället.

En kasseringstilldelning, _ = expression, utvärderar ett uttryck och ignorerar avsiktligt dess resultat. Det är ibland användbart när uttrycket annars inte är en giltig instruktion.

Important

Använd inte _ = Task.Run(...) eller _ = SomeAsyncMethod() för att kassera en uppgift i programkod. Vänta på uppgiften så att dess slutförande och undantag förblir i det anropande flödet. En kasseringstilldelning gör inte en Task säker, observerar inte dess undantag och skapar inte en fire-and-forget-operation som stöds.

Markera oanvända lambda-parametrar

En EventHandler tar emot en object? avsändare och ett EventArgs värde. Följande hanterare behöver ingen parameter. den skriver "Timer tick" bara till konsolen. Om båda parametrarna _ namnges blir deras oanvända status synlig utan att hitta på namn som brödtexten aldrig använder:

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

Välj kasseringsparametrar när en delegatsignatur kräver indataparametrar som lambdauttryckets brödtext inte använder. Om en lambda bara har en parameter med namnet _förblir _ ett vanligt parameternamn för bakåtkompatibilitet.

Undvik _ som identifierare

_ kan vara en vanlig identifierare i sammanhang där C# inte tolkar den som en discard. En variabel som är i scope och heter _ kan tilldelas ett värde på ett sätt som ser ut som en discard-tilldelning. I en mönsterkontext kan en tillgänglig konstant eller typ med namnet _ också ändra hur _ tolkas. Undvik att deklarera dina egna variabler, konstanter eller typer med namnet _; använd _ för att kommunicera avsikten ignorera.

Se även