跳至頁尾內容
Iron Academy Logo
學習C#
學習C#

其他類別

C# 14中的新關鍵字field

[[academy-video-youtube({"vid": "_Z551_SKHA4", "start_time": "0", "title": "The New field Keyword in C# 14", "creator": "Tim Corey", "length": "10m 35s"})]]

C#的自動屬性非常簡潔,但當您需要在設定值器中使用驗證或轉換邏輯時,您一直都必須完全放棄它們,並撰寫一個具有手動備存欄位的完整屬性。 從一行跳到七行是一個急劇的成本,只為了新增一個單一的守護子句。 C# 14引入了field關鍵字來填補這個差距,讓您可以自定義取值器或設值器,而編譯器仍然為您管理備存欄位。

在他的影片中"C# 14中的新field關鍵字",Tim Corey演示了這一特性解決的問題,逐步展示了設定值器驗證的實際例子,並涵蓋了升級前您應該瞭解的一個命名衝突。 我們將詳細跟隨每個步驟,以便您可以有信心地在自己的屬性中使用field

設定:一個簡單的人模型

[0:12 - 1:07] Tim從一個運行在.NET 10和Visual Studio 2026上的控制台應用程式開始。演示集中於一個具有一些屬性的Person類別:

public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }

還有一個由私有欄位支援的Demo屬性,當命名衝突出現時,這成為相關內容。 在LastName = "Corey"的實例,然後列印姓氏、年齡和演示值。 所有輸出如預期那樣:"Corey",0(預設整數),和"test"。

問題:自動屬性接受錯誤資料

[1:23 - 2:49] 當Tim在建構後將LastName時,問題浮出水面:

p.LastName = null;
p.LastName = null;

即使required並被型別化為不可空字串,分配仍然可以編譯。 required修飾符僅在物件初始化期間強制提供一個值; 它無法防止有人在之後將屬性設置為null。 結果是運行時沒有錯誤拋出的空白姓氏。

這是一個現實的資料完整性差距。 型別系統會用可空引用波浪線警告您,但那是編譯時的提示,而不是運行時的保護。 如果您的應用程式依賴於LastName總是包含有效的字串,自動屬性本身無法強制執行那個約定。

舊的修正:帶有手動備存欄位的完整屬性

[2:58 - 4:19] 在C# 14之前,標準解決方法是將自動屬性轉換為帶有顯式備存欄位的完整屬性:

private string _lastName;
public required string LastName
{
    get => _lastName;
    set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
private string _lastName;
public required string LastName
{
    get => _lastName;
    set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}

Tim運行此操作並確認異常會正確觸發:"值不能為空。 參數名稱:LastName。"這種方法可行,但需要聲明一個私有欄位,綁定取值器和設值器,並在多行中重複屬性名稱。 對於單一驗證規則,這是一個很大的儀式。

在這種情況下,取值器沒做什麼特別的; 它返回未更改的欄位。 然而,由於語法要求一旦您離開自動屬性領域,兩個部分都必須顯式撰寫。 Tim將這種繁瑣描述為新特性的動機。

C# 14解決方案:field關鍵字

[4:23 - 5:47] C# 14引入了一個中間解決方案。 與其自己聲明一個私有的備存欄位,不如在取值器或設值器中使用上下文關鍵字field直接引用編譯器生成的備存欄位:

public required string LastName
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
public required string LastName
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}

取值器仍然是自動實現的get;,不需要正文。 設值器使用value賦值。 編譯器建立並管理備存欄位,與標準自動屬性相同。

運行演示會對空值分配產生相同的ArgumentNullException。 行為與手動支援版本相同,從七行壓縮成一個集中只自定義需自定義內容的區塊。 您保留自動屬性取值器,只為設值器新增邏輯,並完全略過手動欄位聲明。

這提供了一個有用的中間步驟,介於單一的自動屬性(一行,無驗證)和完整屬性(七行或更多,完全控制)之間。 當您的邏輯僅限於設值器時,您不再需要支付重寫取值器的語法成本。

用設值器守護驗證年齡

[6:16 - 7:39] 為表明Age屬性新增了範圍驗證:

public int Age
{
    get;
    set
    {
        if (value > 0 && value < 120)
            field = value;
    }
}
public int Age
{
    get;
    set
    {
        if (value > 0 && value < 120)
            field = value;
    }
}

在此,設值器默默忽略了合理範圍以外的值。 分配field從未被寫入。 Tim指出您可以選擇拋出異常,但靜默的方式展示了設值器正文可以包含所需的任意邏輯,同時仍依賴於field作為儲存。

這種模式廣泛適用:夾緊數字範圍,修剪字串中的空白,正規化大小寫,或您每次設置屬性時想應用的任何轉換。

與現有的field變數命名衝突

[7:39 - 9:43] Tim介紹了一個故意的邊界情況。 演示類別有個字面命名為field的私有成員:

private string field = "test";
private string field = "test";

一旦C# 14啟動,編譯器將field視作一個關鍵字而不是變數。 這意味著引用field的屬性默默地從該屬性後面的隱藏儲存讀取(這是空的),而不是包含"test"的字串成員。 輸出變為空白,沒有編譯錯誤,只有警告。

有兩種解決方法。傳入this.field告訴編譯器您指的是類別級別成員,而不是關鍵字。 或者,@field逸出也能以同樣方式工作:

// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;

Tim強烈建議升級到C# 14時重新命名任何名為field的變數。在您的IDE中快速"重新命名所有"可以永久消除歧義。 該衝突僅在屬性取值器內發生; 建構子和方法將field解析為預期的變數名,因為這些上下文中沒有隱式備存。

總結:更少的樣板,無損的控制

[10:04 - 10:28] field關鍵字填補了日常C#程式碼中的實際空白。 需要一個防護子句或轉換的屬性不再需要通過手動備存欄位進行全面重寫。 您僅自定義需要邏輯的取值器,其餘部分保持為標準自動實現。

結論

[10:28 - 10:35] 回顧一下:C# 14的field關鍵字讓您可以直接存取屬性取值器內的隱式備存。 使用它來新增設值器驗證、取值器轉換或兩者,無需為不需自定義的部分放棄自動屬性語法。

在升級之前,搜索您的程式碼庫中任何名為field的變數並將其重命名。 這個預防措施可以避免此功能引入的唯一真正陷阱。 除此之外,它是一個清晰的樣板減少,適合於大多數開發人員已經構建其模型的方式。

範例提示:如果您只需要驗證設值器,則保持取值器為無正文的純粹的get;。 編譯器將其作為自動屬性取值器處理,而您避免撰寫不加任何內容的傳遞回報語句。

觀看他在YouTube上的完整影片並了解更多C#語言功能的見解。

Hero Worlddot related to C# 14中的新關鍵字field
Hero Affiliate related to C# 14中的新關鍵字field

分享您所愛以賺取更多報酬

您是否為使用 .NET、C#、Java、Python 或 Node.js 的開發者建立內容?將您的專業知識轉化為額外收入!

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話