다음을 통해 공유


XML API 설명서 주석 생성

C# 원본 파일에는 해당 파일에 정의된 형식에 대한 API 설명서를 생성하는 구조적 주석이 포함될 수 있습니다. C# 컴파일러는 주석 및 API 서명을 나타내는 구조화된 데이터를 포함하는 XML 파일을 생성합니다. 다른 도구는 XML 출력을 처리하여 웹 페이지 또는 PDF 파일 형식으로 사람이 읽을 수 있는 설명서를 만들 수 있습니다.

이 프로세스는 코드에 API 설명서를 추가하는 데 많은 이점을 제공합니다.

  • C# 컴파일러는 C# 코드의 구조와 주석 텍스트를 단일 XML 문서로 결합합니다.
  • C# 컴파일러는 주석이 관련 태그에 대한 API 서명과 일치하는지 확인합니다.
  • XML 문서 파일을 처리하는 도구는 해당 도구와 관련된 XML 요소 및 특성을 정의할 수 있습니다.

Visual Studio와 같은 도구는 설명서 주석에 사용되는 많은 일반적인 XML 요소에 대한 IntelliSense를 제공합니다.

이 문서에서는 다음 항목을 다룹니다.

  • 설명서 주석 및 XML 파일 생성
  • C# 컴파일러 및 Visual Studio에서 유효성을 검사한 태그
  • 생성된 XML 파일의 형식

XML 설명서 출력 만들기

삼중 슬래시로 표시된 특수 주석 필드를 작성하여 코드에 대한 설명서를 만듭니다. 주석 필드에는 주석 뒤에 있는 코드 블록을 설명하는 XML 요소가 포함됩니다. 다음은 그 예입니다.

/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass { }

GenerateDocumentationFile 또는 DocumentationFile 옵션을 설정하면 컴파일러가 소스 코드에서 XML 태그가 있는 모든 주석 필드를 찾아 해당 주석에서 XML 설명서 파일을 만듭니다. 이 옵션을 사용하도록 설정하면 컴파일러는 XML 설명서 주석 없이 프로젝트에 선언된 공개적으로 표시되는 멤버에 대해 CS1591 경고를 생성합니다.

XML 주석 형식

XML 문서 주석을 사용하려면 설명서 주석이 시작되고 끝나는 위치를 나타내는 구분 기호가 필요합니다. XML 설명서 태그와 함께 다음 구분 기호를 사용합니다.

  • /// 한 줄 구분 기호: 설명서 예제 및 C# 프로젝트 템플릿은 이 양식을 사용합니다. 공백이 구분 기호를 따르는 경우 XML 출력에 포함되지 않습니다.

    비고

    Visual Studio는 코드 편집기에서 <summary> 구분 기호를 입력 /// 한 후 자동으로 해당 태그와 태그를 삽입하고 </summary> 커서를 배치합니다. 옵션 대화 상자에서 이 기능을 켜거나 끌 수 있습니다.

  • /** */ 여러 줄 구분 기호: /** */ 구분 기호에는 다음과 같은 서식 규칙이 있습니다.
    • 구분 기호가 포함된 /** 줄에서 나머지 줄이 공백이면 주석에 대해 줄이 처리되지 않습니다. 구분 기호 뒤의 /** 첫 번째 문자가 공백인 경우 해당 공백 문자는 무시되고 나머지 줄은 처리됩니다. 그렇지 않으면 구분 기호 뒤에 /** 있는 줄의 전체 텍스트가 주석의 일부로 처리됩니다.

    • 구분 기호가 포함된 */ 줄에서 구분 기호까지 */ 공백만 있는 경우 해당 줄은 무시됩니다. 그렇지 않으면 구분 기호까지 줄의 */ 텍스트가 주석의 일부로 처리됩니다.

    • 구분 기호로 시작하는 줄 뒤에 있는 줄의 /** 경우 컴파일러는 각 줄의 시작 부분에서 공통 패턴을 찾습니다. 패턴은 선택적 공백 및/또는 별표(*)와 더 많은 선택적 공백으로 구성될 수 있습니다. 컴파일러가 구분 기호로 시작하거나 구분 기호로 /** 끝나지 */ 않는 각 줄의 시작 부분에서 공통 패턴을 찾으면 각 줄에 대해 해당 패턴을 무시합니다.

    • 처리된 다음 주석의 유일한 부분은 로 시작하는 줄입니다 <summary>. 세 개의 태그 형식은 동일한 주석을 생성합니다.

      /** <summary>text</summary> */
      
      /**
      <summary>text</summary>
      */
      
      /**
      * <summary>text</summary>
      */
      
    • 컴파일러는 두 번째 줄과 세 번째 줄의 시작 부분에서 "* "의 공통 패턴을 식별합니다. 패턴은 출력에 포함되지 않습니다.

      /**
      * <summary>
      * text </summary>*/
      
    • 세 번째 줄의 두 번째 문자는 별표가 아니므로 컴파일러는 다음 주석에서 일반적인 패턴을 찾지 못합니다. 두 번째 줄과 세 번째 줄의 모든 텍스트는 주석의 일부로 처리됩니다.

      /**
      * <summary>
         text </summary>
      */
      
    • 컴파일러는 두 가지 이유로 다음 주석에서 패턴을 찾을 수 없습니다. 첫째, 별표 앞의 공백 수가 일치하지 않습니다. 둘째, 다섯 번째 줄은 공백과 일치하지 않는 탭으로 시작합니다. 2줄에서 5줄의 모든 텍스트는 주석의 일부로 처리됩니다.

      /**
        * <summary>
        * text
      *  text2
       	*  </summary>
      */
      

XML 요소(예: 함수가 XML 설명서 주석에서 설명하려는 특정 XML 요소를 처리함)를 참조하려면 표준 따옴표 메커니즘(&lt;&gt;)을 사용할 수 있습니다. 코드 참조(cref) 요소에서 제네릭 식별자를 참조하려면 이스케이프 문자(예 cref="List&lt;T&gt;": ) 또는 중괄호(cref="List{T}")를 사용할 수 있습니다. 특수한 경우 컴파일러는 중괄호를 꺾쇠 괄호로 구문 분석하여 제네릭 식별자를 참조할 때 설명서 주석이 작성자에게 덜 번거로워지도록 합니다.

비고

한 줄 XML 주석 구분 기호 ///를 사용하여 주석을 작성하지만 태그를 포함하지 않는 경우 컴파일러는 해당 주석의 텍스트를 XML 출력 파일에 추가합니다. 그러나 출력에는 .와 같은 <summary>XML 요소가 포함되지 않습니다. XML 주석(Visual Studio IntelliSense 포함)을 사용하는 대부분의 도구는 이러한 주석을 읽지 않습니다.

XML 설명서 입력을 수락하는 도구

다음 도구는 XML 주석에서 출력을 만듭니다.

  • DocFX: DocFX 는 현재 C#, Visual Basic 및 F#을 지원하는 .NET용 API 설명서 생성기입니다. 또한 생성된 참조 설명서를 사용자 지정할 수 있습니다. DocFX는 소스 코드 및 Markdown 파일에서 정적 HTML 웹 사이트를 빌드합니다. 또한 DocFX는 템플릿을 통해 웹 사이트의 레이아웃과 스타일을 사용자 지정할 수 있는 유연성을 제공합니다. 사용자 지정 템플릿을 만들 수도 있습니다.
  • 샌드캐슬: 샌드캐슬 도구 는 개념 및 API 참조 페이지를 모두 포함하는 관리되는 클래스 라이브러리에 대한 도움말 파일을 만듭니다. 샌드캐슬 도구는 명령줄 기반이며 GUI 프런트 엔드, 프로젝트 관리 기능 또는 자동화된 빌드 프로세스가 없습니다. 샌드캐슬 도움말 파일 작성기는 자동화된 방식으로 도움말 파일을 빌드하는 독립 실행형 GUI 및 명령줄 기반 도구를 제공합니다. Visual Studio 통합 패키지도 사용할 수 있으므로 Visual Studio 내에서 프로젝트를 완전히 만들고 관리할 수 있습니다.
  • Doxygen: Doxygen 은 문서화된 원본 파일 집합에서 온라인 설명서 브라우저(HTML) 또는 오프라인 참조 설명서(LaTeX)를 생성합니다. RTF(MS Word), PostScript, 하이퍼링크 PDF, 압축된 HTML, DocBook 및 Unix 수동 페이지에서 출력을 생성할 수도 있습니다. 문서화되지 않은 소스 파일에서 코드 구조를 추출하도록 Doxygen을 구성할 수 있습니다.

비고

XML 문서 주석은 메타데이터가 아닙니다. 컴파일된 어셈블리에 포함되지 않으므로 리플렉션을 통해 액세스할 수 없습니다.

ID 문자열

각 형식 또는 멤버는 출력 XML 파일의 요소에 저장됩니다. 이러한 각 요소에는 형식 또는 멤버를 식별하는 고유 ID 문자열이 있습니다. ID 문자열은 연산자, 매개 변수, 반환 값, 제네릭 형식 매개 변수 및 refinout 매개 변수를 고려해야 합니다. 이러한 모든 잠재적 요소를 인코딩하기 위해 컴파일러는 ID 문자열을 생성하기 위해 명확하게 정의된 규칙을 따릅니다. XML 파일을 처리하는 프로그램은 ID 문자열을 사용하여 설명서가 적용되는 해당 .NET 메타데이터 또는 리플렉션 항목을 식별합니다.

컴파일러는 ID 문자열을 생성할 때 다음 규칙을 준수합니다.

  • 문자열에 공백이 없습니다.

  • 문자열의 첫 번째 부분은 콜론 뒤에 단일 문자를 사용하여 멤버의 종류를 식별합니다. 사용되는 멤버 형식은 다음과 같습니다.

    캐릭터 멤버 형식 비고
    N 네임스페이스 네임스페이스에 설명서 주석을 추가할 수는 없지만 지원되는 경우 참조할 수 있습니다 cref .
    T 유형 형식은 클래스, 인터페이스, 구조체, 열거형 또는 대리자입니다.
    F 분야
    P 재산 인덱서 또는 기타 인덱싱된 속성을 포함합니다.
    M 메서드 생성자 및 연산자와 같은 특수 메서드를 포함합니다.
    E 이벤트
    ! 오류 문자열 나머지 문자열은 오류에 대한 정보를 제공합니다. C# 컴파일러는 확인할 수 없는 링크에 대한 오류 정보를 생성합니다.
  • 문자열의 두 번째 부분은 네임스페이스의 루트에서 시작하여 항목의 정규화된 이름입니다. 항목의 이름, 항목의 바깥쪽 형식 및 네임스페이스는 마침표로 구분됩니다. 항목 자체의 이름에 마침표가 있는 경우 해시 기호('#')로 바뀝니다. 문법은 이름에 직접 해시 기호가 있는 항목이 없다고 가정합니다. 예를 들어 문자열 생성자의 정규화된 이름은 "System.String.#ctor"입니다.

  • 속성 및 메서드의 경우 괄호로 묶인 매개 변수 목록은 다음과 같습니다. 매개 변수가 없으면 괄호가 없습니다. 매개 변수는 쉼표로 구분됩니다. 각 매개 변수의 인코딩은 .NET 서명에서 인코딩되는 방법을 직접 따릅니다(다음 목록의 모든 대문자 요소 정의 참조 Microsoft.VisualStudio.CorDebugInterop.CorElementType ).

    • 기본 형식입니다. 정규 형식(ELEMENT_TYPE_CLASS 또는 ELEMENT_TYPE_VALUETYPE)은 형식의 정규화된 이름으로 표시됩니다.
    • 내장 형식(예: ELEMENT_TYPE_I4, , ELEMENT_TYPE_OBJECT, ELEMENT_TYPE_STRINGELEMENT_TYPE_TYPEDBYREFELEMENT_TYPE_VOID)은 해당 전체 형식의 정규화된 이름으로 표시됩니다. 예를 들어 System.Int32 또는 System.TypedReference.
    • ELEMENT_TYPE_PTR 는 수정된 형식 다음에 '*'로 표시됩니다.
    • ELEMENT_TYPE_BYREF 는 수정된 형식 다음에 '@'로 표시됩니다.
    • ELEMENT_TYPE_CMOD_OPT 는 수정된 형식에 따라 '!' 및 한정자 클래스의 정규화된 이름으로 표시됩니다.
    • ELEMENT_TYPE_SZARRAY 는 배열의 요소 형식에 따라 "[]"로 표시됩니다.
    • ELEMENT_TYPE_ARRAY 는 [하한:size,하한:size]으로 표현됩니다. 여기서 쉼표 수는 순위 -1이고 각 차원의 하한과 크기(알려진 경우)는 10진수로 표시됩니다. 지정하지 않으면 하한 및 크기가 생략됩니다. 특정 차원의 하한 및 크기를 생략하면 ':'도 생략됩니다. 예를 들어 하한 및 지정되지 않은 크기로 1이 있는 2차원 배열은 [1:,1:]입니다.
  • 변환 연산자(op_Implicitop_Explicit)의 경우 메서드의 반환 값은 뒤에 반환 형식으로 ~ 인코딩됩니다. 예를 들어 클래스 <member name="M:System.Decimal.op_Explicit(System.Decimal arg)~System.Int32"> 에 선언된 캐스트 연산 public static explicit operator int (decimal value); 자의 태그입니다 System.Decimal .

  • 제네릭 형식의 경우 형식 이름 뒤에 백틱과 제네릭 형식 매개 변수 수를 나타내는 숫자가 잇습니다. 예: <member name="T:SampleClass`2"> 로 정의 public class SampleClass<T, U>된 형식에 대 한 태그입니다. 제네릭 형식을 매개 변수로 사용하는 메서드의 경우 제네릭 형식 매개 변수는 백틱 앞에 숫자로 지정됩니다(예: '0,'1). 각 숫자는 형식의 제네릭 매개 변수에 대한 0부터 시작하는 배열 표기법을 나타냅니다.

    • ELEMENT_TYPE_PINNED 는 수정된 형식 다음에 '^'로 표시됩니다. C# 컴파일러는 이 인코딩을 생성하지 않습니다.
    • ELEMENT_TYPE_CMOD_REQ 는 수정된 형식에 따라 '|' 및 한정자 클래스의 정규화된 이름으로 표시됩니다. C# 컴파일러는 이 인코딩을 생성하지 않습니다.
    • ELEMENT_TYPE_GENERICARRAY 는 배열의 요소 형식에 따라 "[?]"로 표시됩니다. C# 컴파일러는 이 인코딩을 생성하지 않습니다.
    • ELEMENT_TYPE_FNPTR 는 반환 형식인 "=FUNC:type(signature)" type 로 표현되고 시그니처 는 메서드의 인수입니다. 인수가 없으면 괄호는 생략됩니다. C# 컴파일러는 이 인코딩을 생성하지 않습니다.
    • 다음 서명 구성 요소는 오버로드된 메서드를 구분하는 데 사용되지 않으므로 표시되지 않습니다.
      • 호출 규칙
      • 반환 형식
      • ELEMENT_TYPE_SENTINEL

다음 예제에서는 클래스 및 해당 멤버의 ID 문자열이 생성되는 방법을 보여 줍니다.

namespace MyNamespace;

/// <summary>
/// Enter description here for class X.
/// ID string generated is "T:MyNamespace.MyClass".
/// </summary>
public unsafe class MyClass
{
    /// <summary>
    /// Enter description here for the first constructor.
    /// ID string generated is "M:MyNamespace.MyClass.#ctor".
    /// </summary>
    public MyClass() { }

    /// <summary>
    /// Enter description here for the second constructor.
    /// ID string generated is "M:MyNamespace.MyClass.#ctor(System.Int32)".
    /// </summary>
    /// <param name="i">Describe parameter.</param>
    public MyClass(int i) { }

    /// <summary>
    /// Enter description here for field Message.
    /// ID string generated is "F:MyNamespace.MyClass.Message".
    /// </summary>
    public string? Message;

    /// <summary>
    /// Enter description for constant PI.
    /// ID string generated is "F:MyNamespace.MyClass.PI".
    /// </summary>
    public const double PI = 3.14;

    /// <summary>
    /// Enter description for method Func.
    /// ID string generated is "M:MyNamespace.MyClass.Func".
    /// </summary>
    /// <returns>Describe return value.</returns>
    public int Func() => 1;

    /// <summary>
    /// Enter description for method SomeMethod.
    /// ID string generated is "M:MyNamespace.MyClass.SomeMethod(System.String,System.Int32@,System.Void*)".
    /// </summary>
    /// <param name="str">Describe parameter.</param>
    /// <param name="num">Describe parameter.</param>
    /// <param name="ptr">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public int SomeMethod(string str, ref int num, void* ptr) { return 1; }

    /// <summary>
    /// Enter description for method AnotherMethod.
    /// ID string generated is "M:MyNamespace.MyClass.AnotherMethod(System.Int16[],System.Int32[0:,0:])".
    /// </summary>
    /// <param name="array1">Describe parameter.</param>
    /// <param name="array">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public int AnotherMethod(short[] array1, int[,] array) { return 0; }

    /// <summary>
    /// Enter description for operator.
    /// ID string generated is "M:MyNamespace.MyClass.op_Addition(MyNamespace.MyClass,MyNamespace.MyClass)".
    /// </summary>
    /// <param name="first">Describe parameter.</param>
    /// <param name="second">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public static MyClass operator +(MyClass first, MyClass second) { return first; }

    /// <summary>
    /// Enter description for property.
    /// ID string generated is "P:MyNamespace.MyClass.Prop".
    /// </summary>
    public int Prop { get { return 1; } set { } }

    /// <summary>
    /// Enter description for event.
    /// ID string generated is "E:MyNamespace.MyClass.OnHappened".
    /// </summary>
    public event Del? OnHappened;

    /// <summary>
    /// Enter description for index.
    /// ID string generated is "P:MyNamespace.MyClass.Item(System.String)".
    /// </summary>
    /// <param name="str">Describe parameter.</param>
    /// <returns></returns>
    public int this[string s] => 1;

    /// <summary>
    /// Enter description for class Nested.
    /// ID string generated is "T:MyNamespace.MyClass.Nested".
    /// </summary>
    public class Nested { }

    /// <summary>
    /// Enter description for delegate.
    /// ID string generated is "T:MyNamespace.MyClass.Del".
    /// </summary>
    /// <param name="i">Describe parameter.</param>
    public delegate void Del(int i);

    /// <summary>
    /// Enter description for operator.
    /// ID string generated is "M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Int32".
    /// </summary>
    /// <param name="myParameter">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public static explicit operator int(MyClass myParameter) => 1;
}

C# 언어 사양

자세한 내용은 설명서 주석에 대한 C# 언어 사양 부록을 참조하세요.