Modificatore obbligatorio (Riferimento a C#)
Il modificatore required
indica che il campo o la proprietà a cui è applicato deve essere inizializzato da un inizializzatore di oggetto . Qualsiasi espressione che inizializza una nuova istanza del tipo deve inizializzare tutti i membri necessari . Il modificatore required
è disponibile a partire da C# 11. Il modificatore required
consente agli sviluppatori di creare tipi in cui le proprietà o i campi devono essere inizializzati correttamente, ma consentono comunque l'inizializzazione usando gli inizializzatori di oggetto. Alcune regole assicurano questo comportamento:
- Il modificatore
required
può essere applicato ai campi e proprietà dichiarate nei tipistruct
eclass
, inclusi i tipirecord
erecord struct
. Il modificatorerequired
non può essere applicato ai membri di uninterface
. - Le implementazioni esplicite dell'interfaccia non possono essere contrassegnate come
required
. Non possono essere impostati negli inizializzatori di oggetti. - I membri obbligatori devono essere inizializzati, ma possono essere inizializzati per
null
. Se il tipo è un tipo riferimento non nullabile, il compilatore genera un avviso se si inizializza il membro anull
. Il compilatore genera un errore se il membro non viene inizializzato affatto. - I membri obbligatori devono essere almeno tanto visibili quanto il loro tipo contenitore. Ad esempio, una classe
public
non può contenere un camporequired
protected
. Inoltre, le proprietà obbligatorie devono avere setter (accessorset
oinit
) che sono almeno altrettanto visibili quanto i tipi che li contengono. I membri che non sono accessibili non possono essere impostati dal codice che crea un'istanza. - Le classi derivate non possono nascondere un membro
required
dichiarato nella classe base. Nascondere un membro richiesto impedisce ai chiamanti di usare gli inizializzatori di oggetto per esso. Inoltre, i tipi derivati che eseguono l'override di una proprietà obbligatoria devono includere il modificatorerequired
. Il tipo derivato non può rimuovere lo statorequired
. I tipi derivati possono aggiungere il modificatorerequired
quando si esegue l'override di una proprietà. - Un tipo con qualsiasi membro
required
non può essere utilizzato come argomento di tipo quando il parametro di tipo include il vincolonew()
. Il compilatore non può imporre che tutti i membri necessari vengano inizializzati nel codice generico. - Il modificatore
required
non è consentito nella dichiarazione per i parametri posizionali in un record. È possibile aggiungere una dichiarazione esplicita per una proprietà posizionale che include il modificatorerequired
.
Alcuni tipi, come i record posizionali , usano un costruttore primario per inizializzare le proprietà posizionali. Se una di queste proprietà include il modificatore required
, il costruttore primario aggiunge l'attributo SetsRequiredMembers
. Ciò indica che il costruttore primario inizializza tutti i membri necessari. È possibile scrivere il proprio costruttore con l'attributo System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute. Tuttavia, il compilatore non verifica che questi costruttori inizializzino tutti i membri necessari. Invece, l'attributo asserisce al compilatore che il costruttore inizializza tutti i membri necessari. L'attributo SetsRequiredMembers
aggiunge queste regole ai costruttori:
- Un costruttore concatenato a un altro costruttore annotato con l'attributo
SetsRequiredMembers
,this()
obase()
, deve includere anche l'attributoSetsRequiredMembers
. Ciò garantisce che i chiamanti possano usare correttamente tutti i costruttori appropriati. - I costruttori di copia generati per i tipi
record
hanno l'attributoSetsRequiredMembers
applicato se uno dei membri èrequired
.
Avvertimento
Il SetsRequiredMembers
disabilita i controlli del compilatore affinché tutti i membri required
vengano inizializzati quando viene creato un oggetto. Usarlo con cautela.
Il codice seguente mostra una gerarchia di classi che usa il modificatore required
per le proprietà FirstName
e 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; }
}
Per altre informazioni sui membri necessari, vedere C#11 - Membri obbligatori specifica della funzionalità.