Partial 멤버(C# 참조)

Partial 멤버에는 하나의 선언적 선언이 있으며 종종 하나의 구현 선언이 있는 경우가 있습니다. 선언적 선언에는 본문이 포함되지 않습니다. 구현 선언은 멤버의 본문을 제공합니다. 클래스 디자이너는 Partial 멤버를 통해 원본 생성기와 같은 도구로 구현할 수 있는 멤버 후크를 제공할 수 있습니다. 부분 형식(Partial Type) 및 멤버는 도구가 형식의 다른 부분을 작성하는 동안 휴먼 개발자가 형식의 일부를 작성하는 방법을 제공합니다. 개발자가 선택적 구현 선언을 제공하지 않는 경우 컴파일러는 컴파일 시간에 선언적 선언을 제거할 수 있습니다. 부분 멤버에는 다음 조건이 적용됩니다.

  • 선언은 상황별 키워드 partial로 시작해야 합니다.
  • 부분 형식의 두 부분에 있는 시그니처가 일치해야 합니다.

partial 키워드는 생성자, 종료자, 오버로드된 연산자 또는 이벤트 선언에서 허용되지 않습니다. C# 13 이전에는 partial이 속성 또는 인덱서에서 허용되지 않았습니다.

부분 메서드는 다음 경우에 구현 선언을 포함할 필요가 없습니다.

해당 일부 제한 사항을 따르지 않는 모든 멤버(public virtual partial void 메서드)는 구현을 제공해야 합니다. Partial 속성 및 인덱서에는 구현이 있어야 합니다.

다음 예제에서는 앞의 제한 사항을 준수하는 부분 메서드를 보여 줍니다.

partial class MyPartialClass
{
    // Declaring definition
    partial void OnSomethingHappened(string s);
}

// This part can be in a separate file.
partial class MyPartialClass
{
    // Comment out this method and the program
    // will still compile.
    partial void OnSomethingHappened(string s) =>
        Console.WriteLine($"Something happened: {s}");
}

Partial 멤버는 소스 생성기와 결합하여 유용하게 사용할 수도 있습니다. 예를 들어, 다음 패턴을 사용하여 regex를 정의할 수 있습니다.

public partial class RegExSourceGenerator
{
    [GeneratedRegex("cat|dog", RegexOptions.IgnoreCase, "en-US")]
    private static partial Regex CatOrDogGeneratedRegex();

    private static void EvaluateText(string text)
    {
        if (CatOrDogGeneratedRegex().IsMatch(text))
        {
            // Take action with matching text
        }
    }
}

앞의 예제에서는 구현 선언이 있어야 하는 부분 메서드를 보여줍니다. 빌드의 일부로서 정규식 원본 생성기는 구현 선언을 만듭니다.

다음 예제에서는 선언적 선언 및 클래스에 대한 구현 선언을 보여 줍니다. 메서드의 반환 형식이 void가 아니고(string임) 해당 액세스가 public이므로, 메서드에 구현 선언이 있어야 합니다.

// Declaring declaration
public partial class PartialExamples
{
    /// <summary>
    /// Gets or sets the number of elements that the List can contain.
    /// </summary>
    public partial int Capacity { get; set; }

    /// <summary>
    /// Gets or sets the element at the specified index.
    /// </summary>
    /// <param name="index">The index</param>
    /// <returns>The string stored at that index</returns>
    public partial string this[int index] { get; set; }

    public partial string? TryGetAt(int index);
}

public partial class PartialExamples
{
    private List<string> _items = [
        "one",
        "two",
        "three",
        "four",
        "five"
        ];

    // Implementing declaration

    /// <summary>
    /// Gets or sets the number of elements that the List can contain.
    /// </summary>
    /// <remarks>
    /// If the value is less than the current capacity, the list will shrink to the
    /// new value. If the value is negative, the list isn't modified.
    /// </remarks>
    public partial int Capacity
    {
        get => _items.Count;
        set
        {
            if ((value != _items.Count) && (value >= 0))
            {
                _items.Capacity = value;
            }
        }
    }

    public partial string this[int index]
    {
        get => _items[index];
        set => _items[index] = value;
    }

    /// <summary>
    /// Gets the element at the specified index.
    /// </summary>
    /// <param name="index">The index</param>
    /// <returns>The string stored at that index, or null if out of bounds</returns>
    public partial string? TryGetAt(int index)
    {
        if (index < _items.Count)
        {
            return _items[index];
        }
        return null;
    }
}

앞의 예제에서는 두 선언이 결합되는 방법에 대한 규칙을 보여 줍니다.

  • 서명 일치: 일반적으로 선언 및 구현 선언에 대한 서명이 일치해야 합니다. 여기에는 메서드, 속성, 인덱서 및 개별 접근자에 대한 접근성 한정자가 포함됩니다. 모든 매개 변수에 대한 매개 변수 형식 및 ref 종류의 한정자가 포함됩니다. 반환 형식 및 ref 종류의 한정자가 일치해야 합니다. 튜플 멤버 이름이 일치해야 합니다. 그러나 일부 규칙은 유연합니다.
    • 선언 및 구현 선언에는 다른 nullable 주석 설정이 있을 수 있습니다. 즉, 하나는 nullable 인식 불가일 수 있고 다른 하나는 null 허용 가능일 수 있습니다.
    • 비인식 Null 허용 여부를 포함하지 않는 Null 허용 여부 차이는 경고를 생성합니다.
    • 기본 매개 변수 값은 일치할 필요가 없습니다. 컴파일러는 메서드 또는 인덱서의 구현 선언이 기본 매개 변수 값을 선언하는 경우 경고를 표시합니다.
    • 매개 변수 이름이 일치하지 않으면 컴파일러에서 경고를 표시합니다. 내보내는 IL에는 선언적 선언의 매개 변수 이름이 포함됩니다.
  • 설명서 주석: 두 선언에서 설명서 주석을 포함할 수 있습니다. 선언 및 구현 선언에 설명서 주석이 모두 포함된 경우 구현 선언의 주석이 포함됩니다. 앞의 예제에서 설명서 주석은 다음을 포함합니다.
    • Capacity 속성의 경우 주석은 구현 선언에서 가져옵니다. 구현 선언 주석은 두 선언에 /// 주석이 있을 때 사용됩니다.
    • 인덱서의 경우 주석은 선언적 선언에서 가져옵니다. 구현 선언에는 /// 주석이 포함되지 않습니다.
    • TryGetAt의 경우 주석은 구현 선언에서 가져옵니다. 선언적 선언에는 /// 주석이 포함되지 않습니다.
    • 생성된 XML에는 모든 public 멤버에 대한 설명서 주석이 있습니다.
  • 대부분의 특성 선언이 결합됩니다. 그러나 모든 호출자 정보 특성AllowMultiple=false로 정의됩니다. 컴파일러는 선언적 선언에서 호출자 정보 특성을 인식합니다. 구현 선언의 모든 호출자 정보 특성은 무시됩니다. 구현 선언에 호출자 정보 특성을 추가하면 컴파일러에서 경고를 표시합니다.

참고 항목