棄牌與棄牌模式

Tip

本文屬於 基礎部分, 適合已經至少懂一種程式語言並正在學習 C# 的開發者。 如果你是紙型新手,可以先從 紙樣搭配概覽開始。 如需完整語法,請參閱捨棄模式參考資料

底線標記(_)表示不需要某個值。 其確切含義取決於出現地點:

Context _ 的意義
切換式表達臂或巢狀模式 一個匹配但不捕捉結果的棄置模式
解構或 out 論證 一個忽略已產生值的捨棄項
像是 _ = expression 這樣的指派 會評估運算式並忽略其結果的 捨棄指定
兩個或以上 lambda 參數,稱為 _ 捨棄 那些未被使用的參數
var _ 呈現某種模式 var帶有棄牌標記的圖案

這些形式在拼寫和意圖上相同,但不能互換。

使用 switch 進行模式比對

在下列範例中, statusCodeint。 每個開關臂會產生 string 訊息,程式會寫入主控台。 最後一個 _ 會處理除了 404200 以外的所有狀態碼:

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

    Console.WriteLine(message);
}

捨棄模式會套用至輸入運算式。 C# 會評估該運算式,而 _ 會比對評估後的值,但不會擷取該值。 當所有先前未處理的值都應採用相同的後援處理時,請選擇 _ 作為 switch 運算式的最後一個 arm。 把它放在最後,因為它符合所有條件,包括 null

該形式 var _ 為帶有捨棄標示的 var 模式。 它也會匹配所有評估值,但不會引入可讀變數。 對於 switch 的 catch-all,請優先使用較短的 _ 捨棄模式。 欲了解更多模式 var 與指定,請參見 宣告、常數及 var 模式

解構聲明

GetForecast 回傳一個包含四個成分的元組:一座 string 城市,以及三個 int 高溫、低溫和降雨機率的值。 解構宣告會保留 cityhigh,因為程式會顯示它們。 它用 _ 來表示低溫和降雨機率,因為命名這些未使用的元件會表示程式碼需要它們:

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

當物件的 Deconstruct 方法會產生數個值時,相同的捨棄語法同樣適用。 關於這些形式,請參見 「解構元組及其他類型」。

呼叫具有 out 參數的方法

假設輸入欄位只在表示整數時接受文字。 該 TryParse(String, Int32) 方法回傳 a bool ,報告解析是否成功。 它也會透過參數out產生解析結果int。 以下程式碼只需布林結果即可接受或拒絕輸入:

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

只有手術成功才重要時才會使用 out _ 。 捨棄項清楚表明不需要剖析出的數字。 如果後續程式碼需要這個數字,請給 out 參數命名,例如 out int number,並保留該值。

棄置指派 _ = expression,評估一個表達式,並故意忽略其結果。 當這個表達本身不是一個有效的陳述時,它偶爾會派上用場。

Important

不要在應用程式程式碼中使用 _ = Task.Run(...)_ = SomeAsyncMethod() 捨棄任務。 等待該工作完成,讓其完成結果與例外狀況都保留在呼叫流程中。 棄置指派不會讓任務安全、觀察例外,或建立支援的「執行後忘記」操作。

標記未使用的lambda參數

一個 EventHandler 會接收一個 object? 傳送端和一個 EventArgs 值。 以下處理器不需要任何參數;它只會寫 "Timer tick" 入主控台。 同時命名兩個參數 _ ,使其未使用的狀態可見,而不必創造身體從未使用過的名稱:

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

當委派簽章需要 Lambda 主體未使用的輸入參數時,請選擇捨棄參數。 若 lambda 只有一個名為 _的參數, _ 則仍為向後相容的普通參數名稱。

避免 _ 作為識別碼

_ 在 C# 無法辨識丟棄的情境中,可以是普通的識別碼。 在範圍內命名 _ 的變數可能會收到看起來像棄置指派的賦值。 在模式內容中,名為 _ 的可存取常數或型別也可能改變 _ 的解讀方式。 避免自行宣告名稱為 _ 的變數、常數或型別;請使用 _ 來表達捨棄意圖。

另請參閱