required modifier (odwołanie w C#)
Modyfikator required
wskazuje, że pole lub właściwość, do którego zastosowano, musi zostać zainicjowane przez inicjator obiektu. Każde wyrażenie, które inicjuje nowe wystąpienie typu, musi zainicjować wszystkie wymagane elementy członkowskie. Modyfikator required
jest dostępny 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
elementy , orazclass
typów, w tymrecord
irecord struct
typów. Modyfikatorrequired
nie może być stosowany do elementów członkowskich obiektuinterface
. - Nie można oznaczyć jawnych implementacji interfejsu jako
required
. Nie można ich ustawić w inicjatorach obiektów. - Wymagane elementy członkowskie muszą zostać zainicjowane, ale mogą zostać zainicjowane na .
null
Jeśli typ jest typem referencyjnym bez wartości null, kompilator wyświetla ostrzeżenie, jeśli zainicjujesz element członkowski nanull
. Kompilator zgłasza błąd, jeśli element członkowski nie został w ogóle zainicjowany. - Wymagane elementy członkowskie muszą być co najmniej tak widoczne, jak ich typ zawierający. Na przykład
public
klasa nie może zawieraćrequired
pola, 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. Elementy członkowskie, które nie są dostępne, nie mogą być ustawiane przez kod, który tworzy wystąpienie. - Klasy pochodne nie mogą ukryć
required
składowej zadeklarowanej w klasie bazowej. Ukrycie wymaganego elementu członkowskiego uniemożliwia obiektom wywołującym używanie inicjatorów obiektów. Ponadto typy pochodne, które zastępują wymaganą właściwość, muszą zawieraćrequired
modyfikator. Typ pochodny nie może usunąćrequired
stanu. Typy pochodne mogą dodawaćrequired
modyfikator podczas zastępowania właściwości. - Typ z żadnymi
required
elementami członkowskimi nie może być używany jako argument typu, gdy parametr typu zawieranew()
ograniczenie. Kompilator nie może wymusić, że wszystkie wymagane elementy członkowskie są inicjowane w kodzie ogólnym. - 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 zawierarequired
modyfikator.
Niektóre typy, takie jak rekordy pozycyjne, używają konstruktora podstawowego do inicjowania właściwości pozycyjnych. Jeśli którakolwiek z tych właściwości zawiera required
modyfikator, podstawowy konstruktor dodaje SetsRequiredMembers
atrybut . Oznacza to, że konstruktor podstawowy inicjuje wszystkie wymagane elementy członkowskie. Możesz napisać własny konstruktor za pomocą atrybutu System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute . Jednak kompilator nie sprawdza, czy te konstruktory inicjują wszystkie wymagane elementy członkowskie. Atrybut potwierdza kompilatorowi, że konstruktor inicjuje wszystkie wymagane elementy członkowskie. Atrybut SetsRequiredMembers
dodaje te reguły do konstruktorów:
- Konstruktor, który tworzy łańcuchy do innego konstruktora z adnotacjami z atrybutem
SetsRequiredMembers
,this()
lubbase()
, musi również zawieraćSetsRequiredMembers
atrybut . Dzięki temu obiekty wywołujące mogą prawidłowo używać wszystkich odpowiednich konstruktorów. - Konstruktory kopiowane wygenerowane dla
record
typów mająSetsRequiredMembers
zastosowany atrybut, jeśli którykolwiek z elementów członkowskich torequired
.
Ostrzeżenie
Funkcja SetsRequiredMembers
wyłącza sprawdzanie kompilatora, że wszystkie required
elementy członkowskie są inicjowane podczas tworzenia obiektu. Należy go używać z ostrożnością.
Poniższy kod przedstawia hierarchię klas, która używa required
modyfikatora dla FirstName
właściwości 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 członków, zobacz specyfikację funkcji C#11 — Wymagane elementy członkowskie .