Komentar dokumentasi XML

File sumber C# dapat memiliki komentar terstruktur yang menghasilkan dokumentasi API untuk jenis yang ditentukan dalam file tersebut. Pengkompilasi C# menghasilkan file XML yang berisi data terstruktur yang mewakili komentar dan tanda tangan API. Alat lain dapat memproses output XML tersebut untuk membuat dokumentasi yang dapat dibaca-manusia dalam bentuk halaman web atau file PDF, misalnya.

Proses ini memberikan banyak keuntungan bagi Anda untuk menambahkan dokumentasi API dalam kode Anda:

  • Pengompilasi C# menggabungkan struktur kode C# dengan teks komentar ke dalam satu dokumen XML.
  • Pengkompilasi C# memverifikasi bahwa komentar cocok dengan tanda tangan API untuk tag yang relevan.
  • Alat yang memproses file dokumentasi XML dapat menentukan elemen dan atribut XML khusus untuk alat tersebut.

Alat seperti Visual Studio menyediakan IntelliSense untuk banyak elemen XML umum yang digunakan dalam komentar dokumentasi.

Artikel ini mencakup topik-topik ini:

  • Komentar dokumentasi dan pembuatan file XML
  • Tag yang divalidasi oleh pengkompilasi dan Visual Studio C#
  • Format file XML yang dihasilkan

Membuat output dokumentasi XML

Anda membuat dokumentasi untuk kode Anda dengan menulis bidang komentar khusus yang ditunjukkan oleh tiga garis miring. Bidang komentar menyertakan elemen XML yang menjelaskan blok kode yang mengikuti komentar. Contohnya:

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

Anda mengatur opsi GenerateDocumentationFile atau DocumentationFile, dan pengkompilasi akan menemukan semua bidang komentar dengan tag XML dalam kode sumber dan membuat file dokumentasi XML dari komentar tersebut. Ketika opsi ini diaktifkan, pengkompilasi menghasilkan peringatan CS1591 untuk setiap anggota yang dapat dilihat publik yang dinyatakan dalam proyek Anda tanpa komentar dokumentasi XML.

Format komentar XML

Penggunaan komentar dokumen XML memerlukan pemisah yang menunjukkan di mana komentar dokumentasi dimulai dan berakhir. Anda menggunakan pemisah berikut dengan tag dokumentasi XML:

  • /// Pemisah baris tunggal: Contoh dokumentasi dan templat proyek C# menggunakan bentuk ini. Jika ada spasi kosong setelah pemisah, tidak disertakan dalam output XML.

    Catatan

    Visual Studio secara otomatis menyisipkan tag <summary> dan </summary> serta menempatkan kursor Anda dalam tag ini setelah Anda mengetik pemisah /// di editor kode. Anda dapat mengaktifkan atau menonaktifkan fitur ini dalam kotak dialog Opsi.

  • /** */ Pemisah multibaris: Pemisah /** */ memiliki aturan pemformatan berikut:
    • Pada baris yang berisi pemisah /**, jika sisa baris adalah spasi kosong, baris tersebut tidak diproses untuk komentar. Jika karakter pertama setelah pemisah /** adalah spasi kosong, karakter spasi putih tersebut diabaikan dan sisa baris diproses. Jika tidak, seluruh teks baris setelah pemisah /** diproses sebagai bagian dari komentar.

    • Pada baris yang berisi pemisah */, jika hanya ada spasi kosong hingga pemisah */, baris tersebut diabaikan. Jika tidak, teks pada baris hingga pemisah */ diproses sebagai bagian dari komentar.

    • Untuk baris setelah baris yang dimulai dengan pemisah /**, pengkompilasi mencari pola umum di awal setiap baris. Pola dapat terdiri dari spasi kosong opsional dan tanda bintang (*), diikuti dengan spasi kosong yang lebih opsional. Jika pengkompilasi menemukan pola umum di awal setiap baris yang tidak dimulai dengan pemisah /** atau diakhir dengan pemisah */, pengkompilasi akan mengabaikan pola tersebut untuk setiap baris.

    • Satu-satunya bagian dari komentar berikut yang diproses adalah baris yang dimulai dengan <summary>. Tiga format tag menghasilkan komentar yang sama.

      /** <summary>text</summary> */
      
      /**
      <summary>text</summary>
      */
      
      /**
      * <summary>text</summary>
      */
      
    • Pengkompilasi mengidentifikasi pola umum " * " di awal baris kedua dan ketiga. Pola tersebut tidak disertakan dalam output.

      /**
      * <summary>
      * text </summary>*/
      
    • Pengkompilasi tidak menemukan pola umum dalam komentar berikut karena karakter kedua pada baris ketiga bukan tanda bintang. Semua teks pada baris kedua dan ketiga diproses sebagai bagian dari komentar.

      /**
      * <summary>
         text </summary>
      */
      
    • Pengkompilasi tidak menemukan pola dalam komentar berikut karena dua alasan. Pertama, jumlah spasi sebelum tanda bintang tidak konsisten. Kedua, baris kelima dimulai dengan tab, yang tidak cocok dengan spasi. Semua teks dari baris dua sampai lima diproses sebagai bagian dari komentar.

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

Untuk merujuk elemen XML (misalnya, fungsi Anda memproses elemen XML tertentu yang ingin Anda jelaskan dalam komentar dokumentasi XML), Anda dapat menggunakan mekanisme kutipan standar (&lt; dan &gt;). Untuk merujuk ke pengidentifikasi generik dalam elemen referensi kode (cref), Anda dapat menggunakan karakter escape (misalnya, cref="List&lt;T&gt;") atau kurung kurawal (cref="List{T}"). Dalam kasus khusus, pengkompilasi mengurai kurung kurawal sebagai kurung sudut untuk membuat komentar dokumentasi tidak terlalu rumit untuk ditulis ketika merujuk pada pengidentifikasi generik.

Catatan

Komentar dokumentasi XML bukan metadata; komentar ini tidak disertakan dalam rangkaian yang dikompilasi dan karena itu tidak dapat diakses melalui refleksi.

Alat yang menerima input dokumentasi XML

Alat berikut membuat output dari komentar XML:

  • DocFX: DocFX adalah generator dokumentasi API untuk .NET, yang saat ini mendukung C#, Visual Basic, dan F#. Hal itu juga memungkinkan Anda untuk menyesuaikan dokumentasi referensi yang dihasilkan. DocFX membangun situs web HTML statis dari kode sumber dan file Markdown Anda. Selain itu, DocFX memberi Anda fleksibilitas untuk menyesuaikan tata letak dan gaya situs web Anda melalui templat. Anda juga dapat membuat templat kustom.
  • Sandcastle: Alat Sandcastle membuat file bantuan untuk pustaka kelas terkelola yang berisi halaman referensi konseptual dan API. Alat Sandcastle berbasis baris-perintah dan tidak memiliki front-end GUI, fitur manajemen proyek, atau proses build otomatis. Sandcastle Help File Builder menyediakan GUI mandiri dan alat berbasis baris-perintah untuk membangun file bantuan secara otomatis. Paket integrasi Visual Studio juga tersedia untuknya sehingga proyek bantuan dapat dibuat dan dikelola sepenuhnya dari dalam Visual Studio.
  • Doxygen: Doxygen menghasilkan browser dokumentasi on-line (dalam HTML) atau manual referensi off-line (di LaTeX) dari sekumpulan file sumber yang didokumentasikan. Ada juga dukungan untuk menghasilkan output di halaman RTF (MS Word), PostScript, PDF hyperlink, HTML terkompresi, DocBook, dan Unix man. Anda dapat mengonfigurasi Doxygen untuk mengekstrak struktur kode dari file sumber yang tidak terdokumentasi.

String ID

Setiap jenis atau anggota disimpan dalam satu elemen pada file XML output. Masing-masing elemen tersebut memiliki string ID unik yang mengidentifikasi jenis atau anggota. String ID harus memperhitungkan operator, parameter, nilai pengembalian, parameter jenis generik, parameter ref, in, dan out. Untuk mengodekan semua elemen potensial tersebut, pengkompilasi mengikuti aturan yang ditentukan dengan jelas untuk menghasilkan string ID. Program yang memproses file XML menggunakan string ID untuk mengidentifikasi metadata .NET atau item pantulan yang diterapkan dokumentasi.

Pengkompilasi mengamati aturan berikut saat menghasilkan string ID:

  • Tidak ada spasi kosong dalam string.

  • Bagian pertama dari string mengidentifikasi jenis anggota menggunakan satu karakter diikuti oleh titik dua. Jenis anggota berikut digunakan:

    Karakter Jenis anggota Catatan
    N namespace Anda tidak dapat menambahkan komentar dokumentasi ke namespace, tetapi Anda bisa membuat referensi cref ke dalamnya, jika didukung.
    T jenis Jenisnya adalah kelas, antarmuka, struktur, enum, atau delegasi.
    F bidang
    P properti Termasuk pengindeks atau properti terindeks lainnya.
    M metode Termasuk metode khusus, seperti konstruktor dan operator.
    E peristiwa
    ! string kesalahan String lainnya menyediakan informasi tentang kesalahan. Pengkompilasi C# menghasilkan informasi kesalahan untuk tautan yang tidak dapat diselesaikan.
  • Bagian kedua dari string adalah nama item yang sepenuhnya memenuhi syarat, dimulai dari akar namespace layanan. Nama item, jenis lampirannya, dan namespace dipisahkan oleh titik. Jika nama item itu sendiri memiliki titik, item digantikan oleh tanda hash ('#'). Diasumsikan bahwa tidak ada item yang memiliki tanda hash langsung dalam namanya. Misalnya, nama konstruktor String yang sepenuhnya memenuhi syarat adalah "System.String.#ctor".

  • Untuk properti dan metode, daftar parameter yang diapit tanda kurung mengikuti. Jika tidak ada parameter, tidak ada tanda kurung. Parameter dipisahkan oleh koma. Pengodean setiap parameter mengikuti langsung bagaimana parameter dikodekan dalam tanda tangan .NET (Lihat Microsoft.VisualStudio.CorDebugInterop.CorElementType untuk definisi semua elemen batas dalam daftar berikut):

    • Jenis dasar. Jenis reguler (ELEMENT_TYPE_CLASS atau ELEMENT_TYPE_VALUETYPE) dinyatakan sebagai nama jenis yang sepenuhnya memenuhi syarat.
    • Jenis intrinsik (misalnya, ELEMENT_TYPE_I4, ELEMENT_TYPE_OBJECT, ELEMENT_TYPE_STRING, ELEMENT_TYPE_TYPEDBYREF, dan ELEMENT_TYPE_VOID) dinyatakan sebagai nama yang sepenuhnya memenuhi syarat dari jenis lengkap terkait. Misalnya, System.Int32 atau System.TypedReference.
    • ELEMENT_TYPE_PTR dinyatakan sebagai '*' setelah jenis yang dimodifikasi.
    • ELEMENT_TYPE_BYREF dinyatakan sebagai '@' mengikuti tipe yang dimodifikasi.
    • ELEMENT_TYPE_CMOD_OPT dinyatakan sebagai '!' dan nama kelas pengubah yang sepenuhnya memenuhi syarat, mengikuti jenis yang dimodifikasi.
    • ELEMENT_TYPE_SZARRAY dinyatakan sebagai "[]" mengikuti jenis elemen array.
    • ELEMENT_TYPE_ARRAY dinyatakan sebagai [batasbawah:size,batasbawah:size] di mana jumlah koma adalah peringkat - 1, dan batas bawah dan ukuran dari setiap dimensi, jika diketahui, dinyatakan dalam desimal. Jika batas bawah atau ukuran tidak ditentukan, maka akan dihilangkan. Jika batas bawah dan ukuran untuk dimensi tertentu dihilangkan, maka ':' juga dihilangkan. Misalnya, array dua dimensi dengan 1 sebagai batas bawah dan ukuran yang tidak ditentukan adalah [1:,1:].
  • Untuk operator konversi saja (op_Implicit dan op_Explicit), nilai pengembalian metode dikodekan sebagai ~ diikuti oleh jenis pengembalian. Misalnya: <member name="M:System.Decimal.op_Explicit(System.Decimal arg)~System.Int32"> adalah tag untuk operator cast public static explicit operator int (decimal value); yang dinyatakan di kelas System.Decimal.

  • Untuk jenis generik, nama jenis diikuti oleh backtick lalu angka yang menunjukkan jumlah parameter jenis generik. Misalnya: <member name="T:SampleClass``2"> adalah tag untuk jenis yang didefinisikan sebagai public class SampleClass<T, U>. Untuk metode yang mengambil jenis generik sebagai parameter, parameter jenis generik ditentukan sebagai angka yang diawali dengan backtick (misalnya '0,'1). Setiap angka mewakili notasi array berbasis nol untuk parameter generik jenis.

    • ELEMENT_TYPE_PINNED dinyatakan sebagai '^' setelah jenis yang dimodifikasi. Pengkompilasi C# tidak pernah menghasilkan pengodean ini.
    • ELEMENT_TYPE_CMOD_REQ dinyatakan sebagai '|' dan nama kelas pengubah yang sepenuhnya memenuhi syarat, mengikuti jenis yang dimodifikasi. Pengkompilasi C# tidak pernah menghasilkan pengodean ini.
    • ELEMENT_TYPE_GENERICARRAY dinyatakan sebagai "[?]" mengikuti jenis elemen array. Pengkompilasi C# tidak pernah menghasilkan pengodean ini.
    • ELEMENT_TYPE_FNPTR dinyatakan sebagai "=FUNC:type(signature)", di mana type adalah jenis pengembalian, dan tanda tangan adalah argumen metode. Jika tidak ada argumen, tanda kurung akan dihilangkan. Pengkompilasi C# tidak pernah menghasilkan pengodean ini.
    • Komponen tanda tangan berikut tidak diwakili karena tidak digunakan untuk membedakan metode yang kelebihan beban:
      • Konvensi panggilan
      • jenis kembalian
      • ELEMENT_TYPE_SENTINEL

Contoh berikut menunjukkan bagaimana string ID untuk kelas dan anggotanya dihasilkan:

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() { return 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 nm, 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] { get { return 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) { return 1; }
    }
}

Spesifikasi bahasa C#

Untuk informasi selengkapnya, lihat lampiran Spesifikasi Bahasa C# pada komentar dokumentasi.