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 wstruct
i typówclass
, w tym typówrecord
irecord struct
. Modyfikatorrequired
nie może być stosowany do członówinterface
. - 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 donull
. 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ć polarequired
, które jestprotected
. Ponadto wymagane właściwości muszą mieć metody ustawiające (set
lubinit
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ć modyfikatorrequired
. Typ pochodny nie może usunąć stanurequired
. Typy pochodne mogą używać modyfikatorarequired
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 ograniczenienew()
. 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 modyfikatorrequired
.
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()
lubbase()
, musi również zawierać atrybutSetsRequiredMembers
. Dzięki temu wywołujący mogą prawidłowo używać wszystkich odpowiednich konstruktorów. - Konstruktory kopiujące generowane dla typów
record
mają atrybutSetsRequiredMembers
, jeśli którykolwiek z członków jestrequired
.
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.