Udostępnij za pośrednictwem


required modifier (dokumentacja C#)

Modyfikator required wskazuje, że pole lub właściwość , do których jest stosowany, należy zainicjować za pomocą inicjatora obiektu . Każde wyrażenie, które inicjuje nowe wystąpienie typu, musi inicjalizować wszystkie wymagane elementy członkowskie. Modyfikator required jest dostępny począwszy od języka C# 11. Modyfikator required umożliwia deweloperom tworzenie typów, w których właściwości lub pola muszą być poprawnie zainicjowane, ale nadal zezwalają na inicjowanie przy użyciu inicjatorów obiektów. Kilka reguł zapewnia to zachowanie:

  • Modyfikator required można zastosować do pól i właściwości zadeklarowanych w structi typów class, w tym typów record i record struct. Modyfikator required nie może być stosowany do członów interface.
  • Nie można oznaczyć jawnych implementacji interfejsu jako required. Nie można ich ustawić w inicjatorach obiektów.
  • Wymagane elementy muszą być zainicjowane, ale mogą być ustawione na null. Jeśli typ jest typem referencyjnym, który nie dopuszcza wartości null, kompilator wyświetla ostrzeżenie, jeśli zainicjujesz człon do null. Kompilator zgłasza błąd, jeśli członek nie został w ogóle zainicjowany.
  • Wymagani członkowie muszą być co najmniej tak widoczni, jak ich typ zawierający. Na przykład klasa public nie może zawierać pola required, które jest protected. Ponadto wymagane właściwości muszą mieć metody ustawiające (set lub init metody dostępu), które są co najmniej tak widoczne, jak ich typy zawierające. Członkowie, którzy nie są dostępni, nie mogą być ustawiani przez kod tworzący instancję.
  • Klasy pochodne nie mogą ukryć składowej required zadeklarowanej w klasie bazowej. Ukrycie wymaganego członka uniemożliwia użytkownikom korzystanie z inicjatorów obiektów. Ponadto typy pochodne, które zastępują wymaganą właściwość, muszą zawierać modyfikator required. Typ pochodny nie może usunąć stanu required. Typy pochodne mogą używać modyfikatora required podczas zastępowania właściwości.
  • Typ z żadnymi elementami członkowskimi required może nie być używany jako argument typu, gdy parametr typu zawiera ograniczenie new(). Kompilator nie może wymusić, że wszyscy wymagani członkowie są inicjowani w kodzie generycznym.
  • Modyfikator required nie jest dozwolony w deklaracji parametrów pozycyjnych w rekordzie. Można dodać jawną deklarację dla właściwości pozycyjnej, która zawiera modyfikator required.

Niektóre typy, takie jak rekordy pozycyjne , używają konstruktora głównego do inicjowania właściwości pozycyjnych. Jeśli którakolwiek z tych właściwości zawiera modyfikator required, konstruktor podstawowy dodaje atrybut SetsRequiredMembers. Oznacza to, że konstruktor podstawowy inicjuje wszystkich wymaganych członków. Możesz napisać własny konstruktor za pomocą atrybutu System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute. Jednak kompilator nie sprawdza, czy te konstruktory inicjują wszystkie wymagane pola. Atrybut zapewnia kompilatorowi, że konstruktor inicjuje wszystkie wymagane składowe. Atrybut SetsRequiredMembers dodaje te reguły do konstruktorów:

  • Konstruktor, który łączy się z innym konstruktorem oznaczonym atrybutem SetsRequiredMembers, this()lub base(), musi również zawierać atrybut SetsRequiredMembers. Dzięki temu wywołujący mogą prawidłowo używać wszystkich odpowiednich konstruktorów.
  • Konstruktory kopiujące generowane dla typów record mają atrybut SetsRequiredMembers, jeśli którykolwiek z członków jest required.

Ostrzeżenie

SetsRequiredMembers wyłącza sprawdzanie przez kompilator, czy wszystkie elementy członkowskie required są inicjowane podczas tworzenia obiektu. Należy go używać z ostrożnością.

Poniższy kod przedstawia hierarchię klas, która używa modyfikatora required dla właściwości FirstName i LastName:

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

Aby uzyskać więcej informacji na temat wymaganych elementów członkowskich, zobacz specyfikację funkcji C#11 — Wymagane elementy członkowskie.