Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Исходные файлы C# могут содержать структурированные комментарии, которые создают документацию ПО API для типов, определенных в этих файлах. Компилятор C# создает XML-файл , содержащий структурированные данные, представляющие комментарии и подписи API. Другие средства могут обрабатывать выходные данные XML для создания документации, доступной для чтения человеком, в виде веб-страниц или PDF-файлов, например.
Этот процесс предоставляет множество преимуществ для добавления документации ПО 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-файле. Каждый из этих элементов имеет уникальную строку идентификатора, которая определяет тип или член. Строка идентификатора должна учитывать операторы, параметры, возвращаемые значения, параметры универсального типа, ref
in
и 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_STRING
,ELEMENT_TYPE_TYPEDBYREF
и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# по комментариям к документации.