modificatore required (Riferimento per C#)

Il modificatore required indica che il campo o la proprietà a cui viene applicato deve essere inizializzato da un inizializzatore di oggetto. Qualsiasi espressione che inizializza una nuova istanza del tipo deve inizializzare tutti i membri richiesti. Il modificatore required è disponibile a partire da C# 11. Il modificatore required abilita gli sviluppatori a creare tipi in cui le proprietà o i campi devono essere inizializzati correttamente, pur consentendo di inizializzarli usando inizializzatori di oggetti. Alcune regole assicurano questo comportamento:

  • Il modificatore required può essere applicato ai campi e alle proprietà dichiarate in struct, nonché ai tipi class, tra cui i tipi record e record struct. Il modificatore required non può essere applicato ai membri di un interface.
  • Le implementazioni esplicite dell'interfaccia non possono essere contrassegnate come required. Queste non possono essere impostate negli inizializzatori di oggetto.
  • I membri richiesti devono essere inizializzati, ma potrebbero essere inizializzati in null. Se il tipo è un tipo riferimento che non ammette i valori Null, non, il compilatore genera un avviso se si inizializza il membro in null. Se il membro non viene inizializzato, il compilatore genera un errore.
  • II membri richiesti devono essere visibili almeno quanto il tipo che li contiene. Ad esempio, una classe public non può contenere un campo required che sia protected. Inoltre, le proprietà richieste devono disporre di setter (funzioni di accesso set o init) che siano visibili almeno 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 di base. Se si nasconde un membro richiesto, i chiamanti non possono usare inizializzatori di oggetto. Inoltre, i tipi derivati che eseguono l'override di una proprietà richiesta devono includere il modificatore required. Il tipo derivato non può rimuovere lo stato required. I tipi derivati possono aggiungere il modificatore required quando si esegue l'override di una proprietà.
  • Un tipo con membri required non può essere utilizzato come argomento tipo quando il parametro di tipo include il vincolo new(). Il compilatore non può imporre che tutti i membri richiesti vengano inizializzati nel codice generico.
  • Il modificatore required non è ammesso nella dichiarazione per i parametri posizionali in un record. È possibile aggiungere una dichiarazione esplicita per una proprietà posizionale che include il modificatore required.

Alcuni tipi, ad esempio i record posizionali, usano un costruttore primario per inizializzare le proprietà posizionali. Se una di queste proprietà include il modificatorerequired, il costruttore primario aggiunge l'attributo SetsRequiredMembers. Ciò indica che il costruttore primario inizializza tutti i membri richiesti. È possibile scrivere il proprio costruttore con l'attributo System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute. Tuttavia, il compilatore non verifica che questi costruttori inizializzino tutti i membri richiesti. Per lo più, è l'attributo ad indicare al compilatore che il costruttore inizializza tutti i membri richiesti. L'attributo SetsRequiredMembers aggiunge le regole seguenti ai costruttori:

  • Un costruttore concatenato a un altro costruttore annotato con l'attributo SetsRequiredMembers, this() o base(), deve includere anche l'attributo SetsRequiredMembers. Ciò garantisce che i chiamanti possano usare correttamente tutti i costruttori appropriati.
  • Ai costruttori di copia generati per i tipi record viene applicato l'attributo SetsRequiredMembers se uno dei membri è required.

Avviso

SetsRequiredMembers disabilita i controlli del compilatore per verificare che tutti i membri required siano inizializzati quando un oggetto viene creato. Usarla 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 richiesti, vedere la specifica della funzionalità C#11 - Membri richiesti.