Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Исходные файлы C# могут содержать структурированные комментарии, которые создают документацию ПО API для типов, определенных в этих файлах. Компилятор C# создает XML-файл , содержащий структурированные данные, представляющие комментарии и подписи API. Другие средства могут обрабатывать выходные данные XML для создания документации, доступной для чтения человеком, в виде веб-страниц или PDF-файлов, например.
Справочные документы на языке C#, выпущенные последней версией языка C#. Она также содержит начальную документацию по функциям в общедоступных предварительных версиях для предстоящего языкового выпуска.
Документация определяет любую функцию, впервые представленную в последних трех версиях языка или в текущих общедоступных предварительных версиях.
Подсказка
Чтобы узнать, когда функция впервые появилась в C#, ознакомьтесь со статьей по журналу версий языка C#.
Этот процесс предоставляет множество преимуществ для добавления документации ПО API в код:
- Компилятор C# объединяет структуру кода C# с текстом комментариев в один XML-документ.
- Компилятор C# проверяет, соответствуют ли комментарии подписям API для соответствующих тегов.
- Средства, обрабатывающие XML-файлы документации, могут определять XML-элементы и атрибуты, относящиеся к этим средствам.
Такие инструменты, как Visual Studio, предоставляют IntelliSense для многих распространенных XML-элементов, используемых в комментариях документации.
В этой статье рассматриваются следующие разделы:
- Комментарии к документации и создание XML-файла
- Теги, проверенные компилятором C# и Visual Studio
- Формат созданного XML-файла
Создание выходных данных XML-документации
Вы создаете документацию для кода, написав специальные поля комментариев, обозначаемые тройной косой чертой. Поля комментариев включают XML-элементы, описывающие блок кода, который следует комментариям. Рассмотрим пример.
/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass { }
Вы задаете параметр GenerateDocumentationFile или DocumentationFile . Компилятор находит все поля комментариев с XML-тегами в исходном коде и создает XML-файл документации из этих комментариев. При включении этого параметра компилятор создает предупреждение CS1591 для любого открыто видимого члена, объявленного в проекте без комментариев xml-документации.
Форматы комментариев 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> */Компилятор не находит шаблон в следующем комментарии по двум причинам. Во-первых, количество пробелов перед звездочкой не согласовано. Во-вторых, пятая строка начинается с вкладки, которая не соответствует пробелам. Весь текст из строк два–пять обрабатывается как часть комментария.
/** * <summary> * text * text2 * </summary> */
Чтобы ссылаться на XML-элементы (например, функция обрабатывает определенные XML-элементы, которые вы хотите описать в комментариях xml-документации), используйте стандартный механизм кавычения (< и >). Чтобы ссылаться на универсальные идентификаторы в элементах ссылки на код (cref), используйте escape-символы (например, cref="List<T>") или фигурные скобки (cref="List{T}"). В качестве специального случая, компилятор анализирует фигурные скобки как угловые, чтобы сделать комментарий к документации менее трудоемким для автора при обращении к универсальным идентификаторам.
Примечание.
Если вы пишете комментарии с помощью разделителя комментариев XML одной строки, но не включают теги, ///компилятор добавляет текст этих примечаний в выходной XML-файл. Однако выходные данные не включают XML-элементы, такие как <summary>. Большинство средств, использующих XML-комментарии (включая IntelliSense Visual Studio), не читают эти комментарии.
Средства, принимаюющие входные данные XML-документации
Следующие средства создают выходные данные из XML-комментариев:
- DocFX: DocFX — это генератор документации по API для .NET, который в настоящее время поддерживает C#, Visual Basic и F#. Он также позволяет настроить созданную справочную документацию. DocFX создает статический HTML-сайт из исходного кода и файлов Markdown. Кроме того, DocFX обеспечивает гибкость в настройке макета и стиля веб-сайта с помощью шаблонов. Вы также можете создавать пользовательские шаблоны.
- Sandcastle: средства Sandcastle создают файлы справки для библиотек управляемых классов, содержащих как концептуальные, так и справочные страницы API. Средства Sandcastle работают на основе командной строки и не имеют интерфейса графического пользователя, функций управления проектами или автоматизированного процесса сборки. Построитель файлов справки Sandcastle предоставляет автономные графические интерфейсы и средства на основе командной строки для создания файла справки автоматически. Пакет интеграции Visual Studio также доступен для него, чтобы помочь проектам создавать и управлять ими полностью из Visual Studio.
- Doxygen: Doxygen создает веб-браузер документации (в HTML) или автономное справочное руководство (в LaTeX) из набора документированных исходных файлов. Кроме того, поддерживается создание выходных данных в RTF (MS Word), PostScript, гиперссылочных PDF, сжатых HTML, DocBook и страниц руководства Unix. Можно настроить Doxygen для извлечения структуры кода из незадокументированных исходных файлов.
Примечание.
Комментарии xml-документации не являются метаданными. Компилятор не включает их в скомпилированную сборку, поэтому они недоступны через отражение.
Строки идентификатора
Компилятор записывает каждый тип или член в элемент в выходном XML-файле. Каждый элемент имеет уникальную строку идентификатора, которая идентифицирует тип или элемент. Строка идентификатора содержит сведения о операторах, параметрах, возвращаемых значениях, параметрах универсального типа, refinи out параметрах. Чтобы закодировать все эти потенциальные элементы, компилятор следует четко определенным правилам для создания строк идентификатора. Программы, обрабатывающие XML-файл, используют строку идентификатора, чтобы определить соответствующие метаданные или элемент отражения .NET, к которому применяется документация.
Компилятор следует этим правилам при создании строк идентификатора:
Строка не содержит пробелов.
Строка начинается с одного символа и двоеточия, определяющего тип элемента. Используйте следующие типы элементов:
Персонаж Тип участника Примечания. Nпространство имен Вы не можете добавлять документационные комментарии в пространство имен, но вы можете делать ссылки crefна них, если это поддерживается.Tтип Тип — это класс, интерфейс, структура, перечисление или делегат. Fполе Pсвойство Включает индексаторы или другие индексированные свойства. Mметод Включает специальные методы, такие как конструкторы и операторы. Eсобытие !Строка ошибки Остальная часть строки содержит сведения об ошибке. Компилятор C# создает сведения об ошибке для ссылок, которые не могут быть разрешены. Вторая часть строки — это полностью квалифицированное имя элемента, начиная с корня пространства имен. Имя элемента, его вложенные типы и пространство имен разделяются точками. Если имя самого элемента имеет периоды, компилятор заменяет их хэш-знаком ('#). В грамматике предполагается, что у элемента нет хэш-входа непосредственно в его имя. Например, полное имя конструктора String — System.String.#ctor.
Для свойств и методов следует список параметров, заключенный в скобки. Если нет параметров, круглые скобки отсутствуют. Параметры разделены запятыми. Кодировка каждого параметра следует непосредственно тому, как он закодирован в сигнатуре .NET (см. Microsoft.VisualStudio.CorDebugInterop.CorElementType для определений всех элементов, написанных заглавными буквами, в следующем списке):
- Базовые типы. Регулярные типы (
ELEMENT_TYPE_CLASSилиELEMENT_TYPE_VALUETYPE) представляются как полное имя типа. - Встроенные типы, такие как
ELEMENT_TYPE_I4,ELEMENT_TYPE_OBJECT,ELEMENT_TYPE_TYPEDBYREFELEMENT_TYPE_STRINGиELEMENT_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, а нижние границы и размер каждого измерения, если известно, представлены в десятичном разряде. Нижние границы и размер опущены, если они не указаны. Если нижняя граница и размер для определенного измерения опущены, то ":" также не отображается. Например, двухмерный массив с 1 в качестве нижних границ и неопределенных размеров равен [1:,1:].
- Базовые типы. Регулярные типы (
Только для операторов преобразования (
op_Implicitиop_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). Каждое число представляет нотацию массива на основе нуля для универсальных параметров типа.-
ELEMENT_TYPE_PINNEDобозначается как "^" после модифицированного типа. Компилятор C# никогда не создает эту кодировку. -
ELEMENT_TYPE_CMOD_REQпредставляется как "|" и полное имя класса модификатора после измененного типа. Компилятор C# никогда не создает эту кодировку. -
ELEMENT_TYPE_GENERICARRAYпредставляется как "[?]" после типа элемента массива. Компилятор C# никогда не создает эту кодировку. -
ELEMENT_TYPE_FNPTRпредставляется как "=FUNC:type(signature)", где является тип возвращаемого значения, аtype— аргументы метода. Если аргументов нет, скобки опущены. Компилятор C# никогда не создает эту кодировку. - Следующие компоненты подписи не представлены, так как они не используются для различения перегруженных методов:
- Соглашение о вызовах
- тип возвращаемого значения
ELEMENT_TYPE_SENTINEL
-
В следующих примерах показано, как компилятор создает строки идентификатора для класса и его членов:
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# по комментариям к документации.