closed(C# 참조)

C# 15부터 클래스에 closed 한정자를 적용하여 닫힌 계층을 선언할 수 있습니다. 선언 어셈블리 내의 닫힌 클래스에서 직접 하위 형식만 파생할 수 있습니다. 직접 하위 항목 집합이 고정 switch 되어 있으므로 각 직계 하위 항목을 처리하는 식은 닫힌 기본 형식을 소모하며 기본 arm이 필요하지 않습니다.

// Assembly 1
public closed record class JobStatus;
public record class Queued : JobStatus;
public record class Running(int PercentComplete) : JobStatus;
public record class Completed(TimeSpan Elapsed) : JobStatus;
public record class Failed(string Error) : JobStatus;

// Assembly 2
public record class Paused : JobStatus; // Error: 'JobStatus' is a closed class

동일한 어셈블리 제한은 닫힌 클래스의 직접 하위 항목에만 적용됩니다. 닫힌 클래스에서 파생되는 클래스는 사용자가 표시 closed하지 않는 한 자체 닫혀 있지 않습니다. Failed 이전 예제에서는 일반 레코드이므로 다른 어셈블리가 파생할 수 있습니다.

// Assembly 2
public record class RetryableFailed(string Error, int Attempts) : Failed(Error); // OK: 'Failed' isn't sealed or closed

파생 을 방지하려면 파생을 로 선언하거나

C# 언어 참조는 가장 최근에 릴리스된 C# 언어 버전을 문서화합니다. 또한 예정된 언어 릴리스의 공개 미리 보기 기능에 대한 초기 설명서도 포함되어 있습니다.

설명서는 언어의 마지막 세 버전 또는 현재 공개 미리 보기에서 처음 도입된 기능을 식별합니다.

Tip

C#에서 기능이 처음 도입된 시기를 찾으려면 C# 언어 버전 기록에 대한 문서를 참조하세요.

메모

closed 는 상황에 맞는 키워드입니다. 클래스 선언에서 한정자로 표시되는 경우에만 특별한 의미가 있습니다. 다른 컨텍스트에서 식별자로 계속 사용할 closed 수 있습니다. 한정자가 유효한 위치에서 식별자로 사용해야 closed 하는 경우 컴파일러에 한정자가 아닌 식별자로 처리하도록 지시하는 접두사(예@: )를 접두 @closed 사로 지정합니다.

선언 규칙

한 closed 정자는 클래스 한정자입니다.

  • closed 클래스는 암시적으로 abstract. 또는 명시적 closed 한정자와 결합 sealedstaticabstract할 수 없습니다.
  • 닫힌 기본 클래스와 동일한 어셈블리 및 모듈에서 닫힌 클래스의 직접 하위 형식을 선언해야 합니다.
  • 닫힌 클래스에서 파생되는 클래스 자체는 닫혀 있지 않습니다. 파생 클래스도 closed 닫으려면 한정자를 다시 적용합니다.

제네릭 클래스가 클래스에서 closed 직접 파생되는 경우 파생 클래스의 모든 형식 매개 변수를 기본 클래스 사양에서 사용해야 합니다. 닫힌 생성 형식은 형식 인수가 완전히 지정된 제네릭 형식입니다(예: Tree<int>열린 형식과는 Tree<T>반대). 열려 있는 형식은 형식 매개 변수인 경우와 같이 Dictionary<string, TValue>TValue 일부 형식 인수를 지정할 수도 있습니다. 정의는 언어 사양에서 열기 및 닫힌 형식 을 참조하세요. 이 제한을 통해 컴파일러는 지정된 기본 생성에 대해 가능한 생성된 하위 항목을 결정할 수 있습니다. 특정 기본 생성에는 특정 하위 항목의 해당 생성이 있을 수 없습니다. 규칙은 하나를 보장하지 않습니다.

public closed record class Tree<T>;

public record class Leaf<T>(T Value) : Tree<T>;                       // OK: 'T' appears in the base class
public record class Branch<T>(Tree<T> Left, Tree<T> Right) : Tree<T>; // OK: 'T' appears in the base class
public record class Constant<U>(U Value) : Tree<int> { } // Error: 'U' isn't used in the base class

완전 스위치 식

식이 switch 닫힌 클래스의 모든 직계 하위 항목을 처리하는 경우 컴파일러는 스위치를 완전하게 간주하고 완전하지 않은 경고를 생성하지 않습니다.

public static string Describe(JobStatus status) => status switch
{
    Queued => "waiting to start",
    Running(var percent) => $"{percent}% complete",
    Completed(var elapsed) => $"finished in {elapsed.TotalSeconds:F1}s",
    Failed(var error) => $"failed: {error}",
    // No warning: every direct descendant of 'JobStatus' is handled.
};

스위치 제어 식이 nullable null 이면 스위치가 처리해야 하는 또 다른 가능한 값이 됩니다. 스위치는 JobStatus? 다음을 포함하는 경우에만 완전합니다.null

public static string DescribeOrUnknown(JobStatus? status) => status switch
{
    null => "unknown",
    Queued => "waiting to start",
    Running(var percent) => $"{percent}% complete",
    Completed(var elapsed) => $"finished in {elapsed.TotalSeconds:F1}s",
    Failed(var error) => $"failed: {error}",
    // No warning: every direct descendant of 'JobStatus' is handled, and null is handled.
};

암을 null 생략하면 컴파일러는 패턴 null 이 처리되지 않는다고 경고합니다. 한 closed 정자는 레코드 클래스를 포함하여 클래스에만 적용됩니다.

닫힌 계층이 제네릭 제약 조건 및 접근성과 상호 작용하는 방법을 포함하여 컴파일러가 완전성을 결정하는 방법에 대한 자세한 내용은 닫힌 계층 패턴을 참조하세요.

닫힌 형식으로 제한되는 형식 매개 변수

닫힌 계층 기능 사양은 닫힌 클래스로 제한되는 형식 매개 변수를 완전성 검사를 위해 닫힌 클래스와 동일하게 처리합니다. switch 형식 매개 변수가 메서드에 표시되는지 또는 포함하는 형식에 표시되는지에 관계없이 종결된 제약 조건의 모든 직계 하위 항목을 처리할 때 해당 형식 매개 변수가 있는 식은 완전합니다.

public static string DescribeJob<X>(X status) where X : JobStatus => status switch
{
    Queued => "waiting to start",
    Running(var percent) => $"{percent}% complete",
    Completed(var elapsed) => $"finished in {elapsed.TotalSeconds:F1}s",
    Failed(var error) => $"failed: {error}",
    // No warning: 'X' is constrained to a closed type, so the compiler treats
    // this switch as exhaustive because every direct descendant is handled.
};

C# 언어 사양

자세한 내용은 닫힌 계층 기능 사양을 참조하세요.

참고하십시오