Modificador required (referencia de C#)
El modificador required
indica que el campo o la propiedad a los que se aplica se deben inicializar mediante un inicializador de objeto. Cualquier expresión que inicialice una nueva instancia del tipo debe inicializar todos los miembros obligatorios. El modificador required
está disponible a partir de C# 11. El modificador required
permite a los desarrolladores crear tipos en los que las propiedades o los campos se deben inicializar correctamente, aunque todavía se permite la inicialización mediante inicializadores de objetos. Varias reglas garantizan este comportamiento:
- El modificador
required
se puede aplicar a campos y propiedades declarados en los tiposstruct
yclass
, incluidosrecord
yrecord struct
. El modificadorrequired
no se puede aplicar a los miembros de un elementointerface
. - Las implementaciones de interfaz explícitas no se pueden marcar como
required
. No se pueden establecer en inicializadores de objetos. - Los miembros obligatorios se deben inicializar, pero se pueden inicializar en
null
. Si el tipo es un tipo de referencia que no acepta valores NULL, el compilador emite una advertencia si inicializa el miembro ennull
. El compilador emite un error si el miembro no se inicializa en absoluto. - Los miembros obligatorios deben ser al menos tan visibles como su tipo contenedor. Por ejemplo, una clase
public
no puede contener un camporequired
que seaprotected
. Además, las propiedades obligatorias deben tener establecedores (los descriptores de accesoset
oinit
) que sean al menos tan visibles como sus tipos contenedores. El código que crea una instancia no puede establecer los miembros a los que no se puede acceder. - Las clases derivadas no pueden ocultar un miembro
required
declarado en la clase base. Ocultar un miembro obligatorio impide que los autores de la llamada usen inicializadores de objeto para él. Además, los tipos derivados que invalidan una propiedad obligatoria deben incluir el modificadorrequired
. El tipo derivado no puede quitar el estadorequired
. Los tipos derivados pueden agregar el modificadorrequired
al invalidar una propiedad. - Es posible que un tipo con algún miembro
required
no se pueda usar como argumento de tipo cuando el parámetro de tipo incluye la restricciónnew()
. El compilador no puede exigir que todos los miembros obligatorios se inicialicen en el código genérico. - El modificador
required
no se permite en la declaración de parámetros posicionales en un registro. Puede agregar una declaración explícita para una propiedad posicional que incluya el modificadorrequired
.
Algunos tipos, como los registros posicionales, usan un constructor principal para inicializar las propiedades posicionales. Si alguna de esas propiedades incluye el modificador required
, el constructor principal agrega el atributo SetsRequiredMembers
. Esto indica que el constructor principal inicializa todos los miembros obligatorios. Puede escribir su propio constructor con el atributo System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute. Sin embargo, el compilador no comprueba que estos constructores inicialicen todos los miembros obligatorios. En su lugar, el atributo afirma al compilador que el constructor inicializa todos los miembros obligatorios. El atributo SetsRequiredMembers
agrega estas reglas a los constructores:
- Un constructor que se encadena a otro constructor anotado con el atributo
SetsRequiredMembers
, ya seathis()
obase()
, también debe incluir el atributoSetsRequiredMembers
. Esto garantiza que los autores de la llamada puedan usar correctamente todos los constructores adecuados. - Los constructores de copia generados para los tipos
record
tienen aplicado el atributoSetsRequiredMembers
si alguno de los miembros esrequired
.
Advertencia
SetsRequiredMembers
deshabilita las comprobaciones del compilador de que todos los miembros required
se inicialicen cuando se crea un objeto. Úsela con precaución.
El código siguiente muestra una jerarquía de clases que usa el modificador required
para las propiedades FirstName
y 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; }
}
Para obtener más información sobre los miembros obligatorios, consulte la especificación de características de C#11 Miembros obligatorios.