共用方式為


必要修飾詞 (C# 參考)

required 修飾詞指定套用其之欄位屬性,必須由物件初始化設定式加以初始化。 任何初始化新類型執行個體的運算式,都必須初始化所有必要成員required 修飾詞自 C# 11 開始提供。 required 修飾詞讓開發人員一方面能夠建立必須正確初始化屬性或欄位的類型,一方面還能繼續使用物件初始化設定式進行初始化。 下列幾項規則可以確保此行為:

  • required 修飾詞可以套用至 structclass 類型中宣告的欄位屬性,包括 recordrecord struct 類型。 required 修飾詞不得套用至 interface 的成員。
  • 明確的介面實作不得標示為 required。 這些實作無法在物件初始化設定式中設定。
  • 必要成員必須初始化,但可以初始化成 null。 若類型是不得為 Null 參考型別,編譯器會在您將成員初始化成 null 時發出警告。 若成員完全未初始化,編譯器會發出錯誤。
  • 必要成員必至少須和其包含類型一起顯示。 例如類別 public 不得包含 protectedrequired 欄位。 此外,必要屬性必須具有 setter (setinit 存取子),其至少須和其包含類型一起顯示。 建立執行個體的程式碼無法設定無法存取的成員。
  • 衍生類別無法隱藏基底類別中宣告的 required 成員。 隱藏必要成員可防止呼叫端使用物件初始化設定式。 此外,覆寫必要屬性的衍生類型必須包含 required 修飾詞。 衍生類型無法移除 required 狀態。 在覆寫屬性時,衍生類型可以新增 required 修飾詞。
  • 當型別參數包含 new() 條件約束時,任何具有 required 成員的類型,都不得用為型別引數。 編譯器無法強制初始化泛型程式碼中的所有必要成員。
  • required 修飾詞不得出現在位置參數的宣告中。 您可以為包含 required 修飾詞的位置屬性,新增明確的宣告。

有一些類型 (例如 位置記錄) 會使用主要建構函式初始化位置屬性。 這些屬性中如有任何屬性包含 required 修飾詞,主要建構函式便會新增 SetsRequiredMembers 屬性。 意即,主要建構函式會初始化所有必要成員。 您可以使用 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 屬性撰寫自己的建構函式。 但編譯器不會驗證這些建構函式是否初始化了所有必要成員。 反而是屬性會判斷提示編譯器,建構函式初始化了所有必要成員。 SetsRequiredMembers 屬性在建構函式中新增下列規則:

  • 鏈結至標註有 SetsRequiredMembers 屬性 (this()base()) 之建構函式的建構函式,也必須包含 SetsRequiredMembers 屬性。 這可確保呼叫端能夠正確使用所有適當的建構函式。
  • 如有任何成員為 required,請複製為 record 類型所產生,並套用了 SetsRequiredMembers 屬性的建構函式。

警告

SetsRequiredMembers 會停用編譯器在物件建立時,檢查所有 required 成員是否均已初始化。 請謹慎使用。

下列程式碼顯示對 FirstNameLastName 屬性使用 required 的類別階層:

public class Person
{
    public Person() { }

    [SetsRequiredMembers]
    public Person(string firstName, string lastName) =>
        (FirstName, LastName) = (firstName, lastName);

    public required string FirstName { get; init; }
    public required string LastName { get; init; }

    public int? Age { get; set; }
}

public class Student : Person
{
    public Student() : base()
    {
    }

    [SetsRequiredMembers]
    public Student(string firstName, string lastName) :
        base(firstName, lastName)
    {
    }

    public double GPA { get; set; }
}

如需必要成員的詳細資訊,請參閱 C#11 - 必要成員功能規格。