필수 한정자(C# 참조)

required 한정자는 적용된 필드 또는 속성개체 이니셜라이저에 의해 초기화되어야 함을 나타냅니다. 해당 형식의 새 인스턴스를 초기화하는 식은 모든 필수 멤버를 초기화해야 합니다. required 한정자는 C# 11부터 사용할 수 있습니다. required 한정자를 사용하면 개발자는 속성이나 필드를 적절하게 초기화해야 하는 형식을 만들면서도 개체 이니셜라이저를 사용한 초기화를 허용할 수 있습니다. 여러 규칙이 이 동작을 보장합니다.

  • required 한정자는 recordrecord struct 형식을 포함하여 structclass 형식에 선언된 필드속성에 적용될 수 있습니다. required 한정자는 interface의 멤버에 적용될 수 없습니다.
  • 명시적 인터페이스 구현은 required로 표시될 수 없습니다. 개체 이니셜라이저에서는 설정할 수 없습니다.
  • 필수 멤버는 초기화되어야 하지만 null로 초기화될 수 있습니다. 형식이 null을 허용하지 않는 참조 형식인 경우 멤버를 null로 초기화하면 컴파일러는 경고를 발급합니다. 멤버가 전혀 초기화되지 않으면 컴파일러에서 오류가 발생합니다.
  • 필수 멤버는 최소한 포함된 형식만큼 표시되어야 합니다. 예를 들어, public 클래스는 protectedrequired 필드를 포함할 수 없습니다. 또한 필수 속성에는 최소한 포함 형식만큼 표시되는 setter(set 또는 init 접근자)가 있어야 합니다. 액세스할 수 없는 멤버는 인스턴스를 만드는 코드로 설정할 수 없습니다.
  • 파생 클래스는 기본 클래스에 선언된 required 멤버를 숨길 수 없습니다. 필수 멤버를 숨기면 호출자가 개체 이니셜라이저를 사용할 수 없습니다. 또한 필수 속성을 재정의하는 파생 형식에는 required 한정자를 포함해야 합니다. 파생 형식은 required 상태를 제거할 수 없습니다. 파생 형식은 속성을 재정의할 때 required 한정자를 추가할 수 있습니다.
  • 형식 매개 변수에 new() 제약 조건이 포함되어 있으면 required 멤버가 있는 형식을 형식 인수로 사용할 수 없습니다. 컴파일러는 모든 필수 멤버가 제네릭 코드에서 초기화되도록 강제할 수 없습니다.
  • 레코드의 위치 매개 변수 선언에는 required 한정자가 허용되지 않습니다. required 한정자를 포함하는 위치 속성에 대한 명시적 선언을 추가할 수 있습니다.

위치 레코드와 같은 일부 형식은 기본 생성자를 사용하여 위치 속성을 초기화합니다. 해당 속성 중 하나라도 required 한정자를 포함하는 경우 기본 생성자는 SetsRequiredMembers 특성을 추가합니다. 이는 기본 생성자가 모든 필수 멤버를 초기화함을 나타냅니다. System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 특성을 사용하여 고유의 생성자를 작성할 수 있습니다. 그러나 컴파일러는 이러한 생성자가 모든 필수 멤버를 초기화하는지 확인하지 않습니다. 오히려 특성은 생성자가 모든 필수 멤버를 초기화한다고 컴파일러에 어설션합니다. SetsRequiredMembers 특성은 생성자에 다음 규칙을 추가합니다.

  • SetsRequiredMembers 특성(this() 또는 base())으로 주석이 달린 다른 생성자에 연결되는 생성자에는 SetsRequiredMembers 특성도 포함되어야 합니다. 이렇게 하면 호출자가 모든 적절한 생성자를 올바르게 사용할 수 있습니다.
  • record 형식에 대해 생성된 복사 생성자에는 멤버 중 하나라도 required인 경우 적용되는 SetsRequiredMembers 특성이 있습니다.

Warning

SetsRequiredMembers는 개체가 만들어질 때 모든 required 멤버가 초기화되는지에 대한 컴파일러 검사를 사용하지 않도록 설정합니다. 주의해서 사용합니다.

다음 코드는 FirstNameLastName 속성에 대해 required 한정자를 사용하는 클래스 계층 구조를 보여 줍니다.

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; }
}

필수 멤버에 대한 자세한 내용은 C#11 - 필수 멤버 기능 사양을 참조하세요.