Поделиться через


Примечания к документации в приложении D

Это приложение информативно.

D.1 General

C# предоставляет механизм для программистов для документирования кода с помощью синтаксиса комментариев, содержащего XML-текст. В файлах исходного кода комментарии с определенной формой можно использовать для направления средства для создания XML из этих комментариев и элементов исходного кода, которые они предшествуют. Комментарии, использующие такой синтаксис, называются комментариями документации. Они должны немедленно предшествовать определяемой пользователем типу (например, классу, делегату или интерфейсу) или члену (например, полю, событию, свойству или методу). Средство создания XML называется генератором документации. (Этот генератор может быть, но не должен быть, сам компилятор C#.) Выходные данные, созданные генератором документации, называются файлом документации. Файл документации используется в качестве входных данных для средства просмотра документации; средство, предназначенное для создания определенного визуального отображения сведений о типах и связанной с ней документации.

Для проверки синтаксиса комментариев документации не требуется соответствующий компилятор C#; такие комментарии просто обычные комментарии. Однако соответствующий компилятор может выполнять такую проверку.

Эта спецификация предполагает, что набор стандартных тегов, используемых в комментариях документации, но использование этих тегов не требуется, а другие теги могут использоваться при необходимости, если требуется выполнение правил хорошо сформированного XML. Для реализаций C# для интерфейса командной строки также содержатся сведения о генераторе документации и формате файла документации. Сведения о средстве просмотра документации не предоставляются.

Введение В D.2

Примечания, имеющие определенную форму, можно использовать для направления средства для создания XML из этих комментариев и элементов исходного кода, которые они предшествуют. Такие комментарии Single_Line_Comment (§6.3.3), которые начинаются с трех косой черты (///), или Delimited_Comments (§6.3.3), которые начинаются с косой черты и двух звездочек (/**). Они должны немедленно предшествовать определяемой пользователем типу или члену, который они заметят. Разделы атрибутов (§22.3) считаются частью объявлений, поэтому комментарии документации должны предшествовать атрибутам, применяемым к типу или члену.

Для экспониментных целей формат комментариев документа показан ниже как два правила грамматики: Single_Line_Doc_Comment и Delimited_Doc_Comment. Однако эти правила не являются частью грамматики C#, а представляют определенные форматы Single_Line_Comment и Delimited_Comment правил лексера соответственно.

Синтаксис

Single_Line_Doc_Comment
    : '///' Input_Character*
    ;
   
Delimited_Doc_Comment
    : '/**' Delimited_Comment_Section* ASTERISK+ '/'
    ;

В Single_Line_Doc_Comment, если символ пробела следует за /// символами на каждом из Single_Line_Doc_Comments, расположенных рядом с текущим Single_Line_Doc_Comment, то символ Пробелы не включены в выходные данные XML.

В Delimited_Doc_Comment, если первый символ без пробелов во второй строке является ASTERISK и тот же шаблон необязательных символов пробелов и символ ASTERISK повторяется в начале каждой строки в Delimited_Doc_Comment, то символы повторяющегося шаблона не включаются в выходные данные XML. Шаблон может включать символы пробелов после, а также до этого символ ASTERISK .

Пример:

/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
public class Point
{
    /// <summary>
    /// Method <c>Draw</c> renders the point.
    /// </summary>
    void Draw() {...}
}

Текст в комментариях документации должен быть хорошо сформирован в соответствии с правилами XML (http://www.w3.org/TR/REC-xml). Если XML-файл не сформирован, создается предупреждение, а файл документации содержит комментарий, указывающий, что возникла ошибка.

Хотя разработчики могут создавать собственный набор тегов, рекомендуемый набор определяется в §D.3. Некоторые рекомендуемые теги имеют особые значения.

  • Тег <param> используется для описания параметров. Если используется такой тег, генератор документации должен убедиться, что указанный параметр существует и что все параметры описаны в комментариях документации. Если такая проверка завершается ошибкой, генератор документации выдает предупреждение.

  • Атрибут cref может быть присоединен к любому тегу для предоставления ссылки на элемент кода. Генератор документации должен убедиться, что этот элемент кода существует. Если проверка завершается ошибкой, генератор документации выдает предупреждение. При поиске имени, описанного cref в атрибуте, генератор документации должен соблюдать видимость пространства имен в соответствии с инструкциями, отображаемыми в исходном коде. Для элементов кода, которые являются универсальными, обычный универсальный синтаксис (например, "List<T>") нельзя использовать, так как он создает недопустимый XML. Фигурные скобки можно использовать вместо квадратных скобок (например, "List{T}") или синтаксис escape-кода XML можно использовать (например, "List&lt;T&gt;").

  • Тег <summary> предназначен для просмотра документации для отображения дополнительных сведений о типе или члене.

  • Тег <include> содержит сведения из внешнего XML-файла.

Обратите внимание, что файл документации не предоставляет полные сведения о типе и членах (например, он не содержит никаких сведений о типах). Чтобы получить такие сведения о типе или члене, файл документации должен использоваться вместе с отражением типа или члена.

D.3.1 General

Генератор документации должен принимать и обрабатывать любой тег, действительный в соответствии с правилами XML. Следующие теги предоставляют часто используемые функции в пользовательской документации. (Конечно, другие теги возможны.)

Тег Справочные материалы Целевые назначения
<c> §D.3.2 Установка текста в шрифте, аналогичном коду
<code> §D.3.3 Установка одной или нескольких строк выходных данных исходного кода или программы
<example> §D.3.4 Указание примера
<exception> §D.3.5 Определяет исключения, которые может вызывать метод.
<include> §D.3.6 Включает XML из внешнего файла
<list> §D.3.7 Создание списка или таблицы
<para> §D.3.8 Разрешение добавления структуры в текст
<param> §D.3.9 Описание параметра для метода или конструктора
<paramref> §D.3.10 Определение того, что слово является именем параметра
<permission> §D.3.11 Документируйте специальные возможности безопасности члена
<remarks> §D.3.12 Описание дополнительных сведений о типе
<returns> §D.3.13 Описание возвращаемого значения метода
<see> §D.3.14 Указание ссылки
<seealso> §D.3.15 Создание записи "См. также"
<summary> §D.3.16 Описание типа или элемента типа
<typeparam> §D.3.17 Описание параметра типа для универсального типа или метода
<typeparamref> §D.3.18 Определение того, что слово является именем параметра типа
<value> §D.3.19 Описание свойства

D.3.2 <c>

Этот тег предоставляет механизм, указывающий, что фрагмент текста в описании должен быть задан в специальном шрифте, например, который используется для блока кода. Для строк фактического кода используйте <code> (§D.3.3).

Синтаксис

<c>text</c>

Пример:

/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
public class Point
{
}

Код D.3.3 <>

Этот тег используется для задания одной или нескольких строк исходного кода или выходных данных программы в определенном специальном шрифте. Для небольших фрагментов кода в повествовании используйте <c> (§D.3.2).

Синтаксис

<code>выходные данные исходного кода или программы</code>

Пример:

public class Point
{
    /// <summary>
    /// This method changes the point's location by the given x- and y-offsets.
    /// <example>
    /// For example:
    /// <code>
    /// Point p = new Point(3,5);
    /// p.Translate(-1,3);
    /// </code>
    /// results in <c>p</c>'s having the value (2,8).
    /// </example>
    /// </summary>
    public void Translate(int dx, int dy)
    {
        ...
    }
}

Пример D.3.4 <>

Этот тег позволяет использовать пример кода в примечании, чтобы указать способ использования метода или другого члена библиотеки. Обычно это также предполагает использование тега <code> (§D.3.3).

Синтаксис

<example>описание</example>

Пример:

Пример см. в разделе <code> (§D.3.3).

Исключение D.3.5 <>

Этот тег предоставляет способ документировать исключения, которые может вызывать метод.

Синтаксис

<exception cref="Описание члена"></exception>

где

  • cref="элемент" — это имя члена. Генератор документации проверяет, существует ли данный элемент и преобразует его в каноническое имя элемента в файле документации.
  • описание обстоятельств, в которых создается исключение.

Пример:

class PrimaryFileFormatCorruptException : System.Exception { ... }
class PrimaryFileLockedOpenException : System.Exception { ... }

public class DataBaseOperations
{
    /// <exception cref="PrimaryFileFormatCorruptException">
    /// Thrown when the primary file is corrupted.
    /// </exception>
    /// <exception cref="PrimaryFileLockedOpenException">
    /// Thrown when the primary file is already open.
    /// </exception>
    public static void ReadRecord(int flag)
    {
        if (flag == 1)
        {
            throw new PrimaryFileFormatCorruptException();
        }
        else if (flag == 2)
        {
            throw new PrimaryFileLockedOpenException();
        }
        ...
    }
}

D.3.6 <включают>

Этот тег позволяет включать сведения из XML-документа, который является внешним для файла исходного кода. Внешний файл должен быть хорошо сформированным XML-документом, и выражение XPath применяется к данному документу, чтобы указать, какой XML-код из этого документа следует включить. Затем <include> тег заменяется выбранным XML из внешнего документа.

Синтаксис

<include file="" path="имя_файла xpath" />

где

  • file="имя" файла — это имя файла внешнего XML-файла. Имя файла интерпретируется относительно файла, содержащего тег включения.
  • path="xpath" — это выражение XPath, которое выбирает некоторые XML-файлы во внешнем XML-файле.

Пример:

Если исходный код содержал объявление, например:

/// <include file="docs.xml" path='extradoc/class[@name="IntList"]/*' />
public class IntList { ... }

и внешний файл "docs.xml" имел следующее содержимое:

<?xml version="1.0"?>
<extradoc>
    <class name="IntList">
        <summary>
            Contains a list of integers.
        </summary>
    </class>
    <class name="StringList">
        <summary>
            Contains a list of strings.
        </summary>
    </class>
</extradoc>

Затем та же документация выводится так же, как если бы исходный код содержался:

/// <summary>
/// Contains a list of integers.
/// </summary>
public class IntList { ... }

Список D.3.7 <>

Этот тег используется для создания списка или таблицы элементов. Он может содержать <listheader> блок для определения строки заголовка таблицы или списка определений. (При определении таблицы необходимо указать только запись для термина в заголовке.)

Каждый элемент в списке указывается в блоке <item>. При создании списка определений необходимо указать как термин, так и описание. Однако для таблицы, маркированного списка или нумерованного списка необходимо указать только описание .

Синтаксис

<list type="bullet" | "number" | "table">
    <listheader>
        <term>term</term>
        <description>description</description>
    </listheader>
    <item>
        <term>term</term>
        <description>description</description>
    </item>
    ...
    <item>
        <term>term</term>
        <description>description</description>
    </item>
</list>

где

  • термин — это термин для определения, определение которого находится в описании.
  • описание — это элемент в маркированном или нумерованном списке или определение термина.

Пример:

public class MyClass
{
    /// <summary>Here is an example of a bulleted list:
    /// <list type="bullet">
    /// <item>
    /// <description>Item 1.</description>
    /// </item>
    /// <item>
    /// <description>Item 2.</description>
    /// </item>
    /// </list>
    /// </summary>
    public static void Main()
    {
        ...
    }
}

D.3.8 <para>

Этот тег предназначен для использования внутри других тегов, таких как <summary> (§D.3.16) или <returns> (§D.3.13), и позволяет добавлять структуру в текст.

Синтаксис

<para>content</para>

где

  • содержимое — это текст абзаца.

Пример:

public class Point
{
    /// <summary>This is the entry point of the Point class testing program.
    /// <para>
    /// This program tests each method and operator, and
    /// is intended to be run after any non-trivial maintenance has
    /// been performed on the Point class.
    /// </para>
    /// </summary>
    public static void Main() 
    {
        ...
    }
}

D.3.9 <param>

Этот тег используется для описания параметра метода, конструктора или индексатора.

Синтаксис

<param name="Описание имени"></param>

где

  • имя параметра.
  • description — это описание параметра.

Пример:

public class Point
{
    /// <summary>
    /// This method changes the point's location to
    /// the given coordinates.
    /// </summary>
    /// <param name="xPosition">the new x-coordinate.</param>
    /// <param name="yPosition">the new y-coordinate.</param>
    public void Move(int xPosition, int yPosition)
    {
        ...
    }
}

D.3.10 <paramref>

Этот тег используется для указания того, что слово является параметром. Файл документации можно обрабатывать для форматирования этого параметра по-разному.

Синтаксис

<paramref name="name"/>

где

  • имя параметра.

Пример:

public class Point
{
    /// <summary>This constructor initializes the new Point to
    /// (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
    /// </summary>
    /// <param name="xPosition">the new Point's x-coordinate.</param>
    /// <param name="yPosition">the new Point's y-coordinate.</param>
    public Point(int xPosition, int yPosition)
    {
        ...
    }
}

Разрешение D.3.11 <>

Этот тег позволяет документировать специальные возможности безопасности члена.

Синтаксис

<permission cref="Описание члена"></permission>

где

  • элемент — это имя члена. Генератор документации проверяет, существует ли заданный элемент кода и преобразует член в каноническое имя элемента в файле документации.
  • description — это описание доступа к члену.

Пример:

public class MyClass
{
    /// <permission cref="System.Security.PermissionSet">
    /// Everyone can access this method.
    /// </permission>
    public static void Test()
    {
        ...
    }
}

Замечания D.3.12 <>

Этот тег используется для указания дополнительных сведений о типе. Используйте <summary> (§D.3.16), чтобы описать сам тип и члены типа.

Синтаксис

<remarks>описание</remarks>

где

  • описание — это текст примечания.

Пример:

/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
/// <remarks>
/// Uses polar coordinates
/// </remarks>
public class Point
{
    ...
}

Возвращается D.3.13 <>

Этот тег используется для описания возвращаемого значения метода.

Синтаксис

<returns>описание</returns>

где

  • description — это описание возвращаемого значения.

Пример:

public class Point
{
    /// <summary>
    /// Report a point's location as a string.
    /// </summary>
    /// <returns>
    /// A string representing a point's location, in the form (x,y),
    /// without any leading, trailing, or embedded whitespace.
    /// </returns>
    public override string ToString() => $"({X},{Y})";
    public int X { get; set; }
    public int Y { get; set; }
}

D.3.14 <см.>

Этот тег позволяет указать ссылку в тексте. Используйте <seealso> (§D.3.15), чтобы указать текст, который будет отображаться в подклаузе "См. также ".

Синтаксис

<see cref="Ключевое слово URL-адресаучастника" href="" langword="" />

где

  • элемент — это имя члена. Генератор документации проверяет, существует ли заданный элемент кода и изменяет его имя в созданном файле документации.
  • URL-адрес является ссылкой на внешний источник.
  • langword — это слово, выделенное каким-то образом.

Пример:

public class Point
{
    /// <summary>
    /// This method changes the point's location to
    /// the given coordinates. <see cref="Translate"/>
    /// </summary>
    public void Move(int xPosition, int yPosition)
    {
        ...
    }
    /// <summary>This method changes the point's location by
    /// the given x- and y-offsets. <see cref="Move"/>
    /// </summary>
    public void Translate(int dx, int dy)
    {
        ...
    }
}

D.3.15 <seealso>

Этот тег позволяет создать запись для подклаузов See Также . Используйте <see> (§D.3.14), чтобы указать ссылку из текста.

Синтаксис

<seealso cref="URL-адрес участника" href="" />

где

  • элемент — это имя члена. Генератор документации проверяет, существует ли заданный элемент кода и изменяет его имя в созданном файле документации.
  • URL-адрес является ссылкой на внешний источник.

Пример:

public class Point
{
    /// <summary>
    /// This method determines whether two Points have the same location.
    /// </summary>
    /// <seealso cref="operator=="/>
    /// <seealso cref="operator!="/>
    public override bool Equals(object o)
    {
        ...
    }
}

Сводка по D.3.16 <>

Этот тег можно использовать для описания типа или члена типа. Используйте <remarks> (§D.3.12), чтобы указать дополнительные сведения о типе или члене.

Синтаксис

<summary>описание</summary>

где

  • описание — это сводка по типу или члену.

Пример:

public class Point
{

    /// <summary>
    /// This constructor initializes the new Point to
    /// (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
    /// </summary>
    public Point(int xPosition, int yPosition) 
    {
        ...
    }

    /// <summary>This constructor initializes the new Point to (0,0).</summary>
    public Point() : this(0, 0)
    {
    }
}

D.3.17 <typeparam>

Этот тег используется для описания параметра типа для универсального типа или метода.

Синтаксис

<typeparam name="Описание имени"></typeparam>

где

  • имя параметра типа.
  • description — это описание параметра типа.

Пример:

/// <summary>A generic list class.</summary>
/// <typeparam name="T">The type stored by the list.</typeparam>
public class MyList<T>
{
   ...
}

D.3.18 <typeparamref>

Этот тег используется для указания того, что слово является параметром типа. Файл документации можно обрабатывать для форматирования этого параметра типа по-разному.

Синтаксис

<typeparamref name="name"/>

где

  • имя параметра типа.

Пример:

public class MyClass
{
    /// <summary>
    /// This method fetches data and returns a list of
    /// <typeparamref name="T"/>.
    /// </summary>
    /// <param name="query">query to execute</param>
    public List<T> FetchData<T>(string query)
    {
        ...
    }
}

Значение D.3.19 <>

Этот тег позволяет описывать свойство.

Синтаксис

<value>Описание свойства</value>

где

  • Описание свойства — это описание свойства.

Пример:

public class Point
{
    /// <value>Property <c>X</c> represents the point's x-coordinate.</value>
    public int X { get; set; }
}

D.4 Обработка файла документации

D.4.1 General

Следующие сведения предназначены для реализаций C#, предназначенных для интерфейса командной строки.

Генератор документации создает строку идентификатора для каждого элемента исходного кода, помеченного комментарием документации. Эта строка идентификатора однозначно идентифицирует исходный элемент. Средство просмотра документации может использовать строку идентификатора для идентификации соответствующего элемента, к которому применяется документация.

Файл документации не является иерархическим представлением исходного кода; скорее, это плоский список с созданной строкой идентификатора для каждого элемента.

Формат строки идентификатора D.4.2

Генератор документации соблюдает следующие правила при создании строк идентификатора:

  • Пробелы в строку не вставляются.

  • Первая часть строки определяет тип задокументированного элемента с помощью одного символа, за которым следует двоеточие. Определены следующие типы элементов:

    Символ Description
    E Мероприятие
    F Поле
    Пн. Метод (включая конструкторы, методы завершения и операторы)
    N Пространство имен
    P Свойство (включая индексаторы)
    T Тип (например, класс, делегат, перечисление, интерфейс и структура)
    ! Строка ошибки; Остальная часть строки содержит сведения об ошибке. Например, генератор документации создает сведения об ошибках для ссылок, которые не могут быть разрешены.
  • Вторая часть строки — полное имя элемента, начиная с корневого каталога пространства имен. Имя элемента, его вложенные типи и пространство имен разделяются точками. Если имя элемента имеет периоды, они заменяются символами #(U+0023). (Предполагается, что элемент не имеет этого знака в его имени.) Аргументы типа в полном имени, если член явно реализует член универсального интерфейса, кодируются заменой "" и "<>" вокруг них символами "{" и "}".

  • Для методов и свойств с аргументами список аргументов следует за скобками. Для тех, кто без аргументов, скобки опущены. Аргументы разделяются запятыми. Кодировка каждого аргумента совпадает с сигнатурой CLI следующим образом:

    • Аргументы представлены их именем документации, которая основана на полном имени, изменена следующим образом:
      • Аргументы, представляющие универсальные типы, имеют добавленный' "" символ, за которым следует число параметров типа
      • Аргументы с модификатором inout или ref модификатором имеют следующее @ имя типа. Аргументы, передаваемые по значению или через params , не имеют специальных нотации.
      • Аргументы, которые являются массивами, представлены как [ более низкий размер , входящего : трафика ... ,нижний трафик : размер ] где число запятых меньше ранга, а нижние границы и размер каждого измерения, если известно, представлены в десятичном разряде. Если нижнюю границу или размер не указан, он опущен. Если нижнюю границу и размер для определенного измерения опущены, то ":" также не указан. Многоуровневые массивы представлены одним "" на уровне[]. Одномерные массивы пропускают нижнюю границу, если нижняя граница — 0 (по умолчанию) (§17.1).
      • Аргументы, имеющие типы указателей, отличные void от представленных, с помощью следующего * имени типа. void Указатель представлен с помощью имени System.Voidтипа.
      • Аргументы, ссылающиеся на параметры универсального типа, определенные для типов, кодируются с помощью символа "`", за которым следует отсчитываемый от нуля индекс параметра типа.
      • Аргументы, использующие параметры универсального типа, определенные в методах, используют двойной обратный символ "``" вместо "`" для типов.
      • Аргументы, ссылающиеся на созданные универсальные типы, кодируются с помощью универсального типа, а затем "{", за которым следует разделенный запятыми список аргументов типов, а затем "}".

Примеры строк идентификатора D.4.3

В следующих примерах показано фрагмент кода C#, а также строка идентификатора, созданная из каждого исходного элемента, способного иметь комментарий к документации:

Типы представлены с помощью полного имени, дополненного универсальными сведениями:

enum Color { Red, Blue, Green }

namespace Acme
{
    interface IProcess { ... }

    struct ValueType { ... }

    class Widget : IProcess
    {
        public class NestedClass { ... }
        public interface IMenuItem { ... }
        public delegate void Del(int i);
        public enum Direction { North, South, East, West }
    }

    class MyList<T>
    {
        class Helper<U,V> { ... }
    }
}

Идентификаторы:

"T:Color"
"T:Acme.IProcess"
"T:Acme.ValueType"
"T:Acme.Widget"
"T:Acme.Widget.NestedClass"
"T:Acme.Widget.IMenuItem"
"T:Acme.Widget.Del"
"T:Acme.Widget.Direction"
"T:Acme.MyList`1"
"T:Acme.MyList`1.Helper`2"

Поля представлены их полным именем.

namespace Acme
{
    struct ValueType
    {
        private int total;
    }

    class Widget : IProcess
    {
        public class NestedClass
        {
            private int value;
        }

        private string message;
        private static Color defaultColor;
        private const double PI = 3.14159;
        protected readonly double monthlyAverage;
        private long[] array1;
        private Widget[,] array2;
        private unsafe int *pCount;
        private unsafe float **ppValues;
    }
}

Идентификаторы:

"F:Acme.ValueType.total"
"F:Acme.Widget.NestedClass.value"
"F:Acme.Widget.message"
"F:Acme.Widget.defaultColor"
"F:Acme.Widget.PI"
"F:Acme.Widget.monthlyAverage"
"F:Acme.Widget.array1"
"F:Acme.Widget.array2"
"F:Acme.Widget.pCount"
"F:Acme.Widget.ppValues"

Конструкторы

namespace Acme
{
    class Widget : IProcess
    {
        static Widget() { ... }
        public Widget() { ... }
        public Widget(string s) { ... }
    }
}

Идентификаторы:

"M:Acme.Widget.#cctor"
"M:Acme.Widget.#ctor"
"M:Acme.Widget.#ctor(System.String)"

Методы завершения

namespace Acme
{
    class Widget : IProcess
    {
        ~Widget() { ... }
    }
}

Идентификаторы:

"M:Acme.Widget.Finalize"

Методы

namespace Acme
{
    struct ValueType
    {
        public void M(int i) { ... }
    }

    class Widget : IProcess
    {
        public class NestedClass
        {
            public void M(int i) { ... }
        }

        public static void M0() { ... }
        public void M1(char c, out float f, ref ValueType v, in int i) { ... }
        public void M2(short[] x1, int[,] x2, long[][] x3) { ... }
        public void M3(long[][] x3, Widget[][,,] x4) { ... }
        public unsafe void M4(char *pc, Color **pf) { ... }
        public unsafe void M5(void *pv, double *[][,] pd) { ... }
        public void M6(int i, params object[] args) { ... }
    }

    class MyList<T>
    {
        public void Test(T t) { ... }
    }

    class UseList
    {
        public void Process(MyList<int> list) { ... }
        public MyList<T> GetValues<T>(T value) { ... } 
    }
}

Идентификаторы:

"M:Acme.ValueType.M(System.Int32)"
"M:Acme.Widget.NestedClass.M(System.Int32)"
"M:Acme.Widget.M0"
"M:Acme.Widget.M1(System.Char,System.Single@,Acme.ValueType@,System.Int32@)"
"M:Acme.Widget.M2(System.Int16[],System.Int32[0:,0:],System.Int64[][])"
"M:Acme.Widget.M3(System.Int64[][],Acme.Widget[0:,0:,0:][])"
"M:Acme.Widget.M4(System.Char*,Color**)"
"M:Acme.Widget.M5(System.Void*,System.Double*[0:,0:][])"
"M:Acme.Widget.M6(System.Int32,System.Object[])"
"M:Acme.MyList`1.Test(`0)"
"M:Acme.UseList.Process(Acme.MyList{System.Int32})"
"M:Acme.UseList.GetValues``1(``0)"

Свойства и индексаторы

namespace Acme
{
    class Widget : IProcess
    {
        public int Width { get { ... } set { ... } }
        public int this[int i] { get { ... } set { ... } }
        public int this[string s, int i] { get { ... } set { ... } }
    }
}

Идентификаторы:

"P:Acme.Widget.Width"
"P:Acme.Widget.Item(System.Int32)"
"P:Acme.Widget.Item(System.String,System.Int32)"

События

namespace Acme
{
    class Widget : IProcess
    {
        public event Del AnEvent;
    }
}

Идентификаторы:

"E:Acme.Widget.AnEvent"

Унарные операторы

namespace Acme
{
    class Widget : IProcess
    {
        public static Widget operator+(Widget x) { ... }
    }
}

Идентификаторы:

"M:Acme.Widget.op_UnaryPlus(Acme.Widget)"

Полный набор унарных имен функций операторов используется следующим образом: op_UnaryPlus, op_UnaryNegation, op_LogicalNot, op_OnesComplement, op_Increment, op_Decrementop_Trueи op_False.

Двоичные операторы

namespace Acme
{
    class Widget : IProcess
    {
        public static Widget operator+(Widget x1, Widget x2) { ... }
    }
}

Идентификаторы:

"M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)"

Полный набор имен функций двоичного оператора используется следующим образом: op_Addition, op_LessThanOrEqualop_BitwiseAndop_BitwiseOrop_Modulusop_ExclusiveOrop_Divisionop_LeftShiftop_RightShiftop_Multiplyop_Subtractionop_Inequalityop_LessThanop_Equalityop_GreaterThanи .op_GreaterThanOrEqual

Операторы преобразования имеют конечный "~", за которым следует возвращаемый тип. Если исходный или целевой объект оператора преобразования является универсальным типом, символы "<" и"> "" заменяются символами "" и "{}" соответственно.

namespace Acme
{
    class Widget : IProcess
    {
        public static explicit operator int(Widget x) { ... }
        public static implicit operator long(Widget x) { ... }
    }
}

Идентификаторы:

"M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32"
"M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64"

Пример D.5

Исходный код D.5.1 C#

В следующем примере показан исходный код класса Point:

namespace Graphics
{
    /// <summary>
    /// Class <c>Point</c> models a point in a two-dimensional plane.
    /// </summary>
    public class Point
    {
        /// <value>
        /// Property <c>X</c> represents the point's x-coordinate.
        /// </value>
        public int X { get; set; }
        
        /// <value>
        /// Property <c>Y</c> represents the point's y-coordinate.
        /// </value>
        public int Y { get; set; }
        
        /// <summary>
        /// This constructor initializes the new Point to (0,0).
        /// </summary>
        public Point() : this(0, 0) {}
        
        /// <summary>
        /// This constructor initializes the new Point to
        /// (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
        /// </summary>
        /// <param name="xPosition">The new Point's x-coordinate.</param>
        /// <param name="yPosition">The new Point's y-coordinate.</param>
        public Point(int xPosition, int yPosition) 
        {
            X = xPosition;
            Y = yPosition;
        }
        
        /// <summary>
        /// This method changes the point's location to
        /// the given coordinates. <see cref="Translate"/>
        /// </summary>
        /// <param name="xPosition">The new x-coordinate.</param>
        /// <param name="yPosition">The new y-coordinate.</param>
        public void Move(int xPosition, int yPosition) 
        {
            X = xPosition;
            Y = yPosition;
        }
        
        /// <summary>
        /// This method changes the point's location by
        /// the given x- and y-offsets.
        /// <example>For example:
        /// <code>
        /// Point p = new Point(3, 5);
        /// p.Translate(-1, 3);
        /// </code>
        /// results in <c>p</c>'s having the value (2, 8).
        /// <see cref="Move"/>
        /// </example>
        /// </summary>
        /// <param name="dx">The relative x-offset.</param>
        /// <param name="dy">The relative y-offset.</param>
        public void Translate(int dx, int dy)
        {
            X += dx;
            Y += dy;
        }
        
        /// <summary>
        /// This method determines whether two Points have the same location.
        /// </summary>
        /// <param name="o">
        /// The object to be compared to the current object.
        /// </param>
        /// <returns>
        /// True if the Points have the same location and they have
        /// the exact same type; otherwise, false.
        /// </returns>
        /// <seealso cref="operator=="/>
        /// <seealso cref="operator!="/>
        public override bool Equals(object o)
        {
            if (o == null)
            {
                return false;
            }
            if ((object)this == o) 
            {
                return true;
            }
            if (GetType() == o.GetType()) 
            {
                Point p = (Point)o;
                return (X == p.X) && (Y == p.Y);
            }
            return false;
        }

        /// <summary>
        /// This method returns a Point's hashcode.
        /// </summary>
        /// <returns>
        /// The int hashcode.
        /// </returns>
        public override int GetHashCode()
        {
            return X + (Y >> 4);    // a crude version
        }
        
        /// <summary>Report a point's location as a string.</summary>
        /// <returns>
        /// A string representing a point's location, in the form (x,y),
        /// without any leading, training, or embedded whitespace.
        /// </returns>
        public override string ToString() => $"({X},{Y})";
        
        /// <summary>
        /// This operator determines whether two Points have the same location.
        /// </summary>
        /// <param name="p1">The first Point to be compared.</param>
        /// <param name="p2">The second Point to be compared.</param>
        /// <returns>
        /// True if the Points have the same location and they have
        /// the exact same type; otherwise, false.
        /// </returns>
        /// <seealso cref="Equals"/>
        /// <seealso cref="operator!="/>
        public static bool operator==(Point p1, Point p2)
        {
            if ((object)p1 == null || (object)p2 == null)
            {
                return false;
            }
            if (p1.GetType() == p2.GetType())
            {
                return (p1.X == p2.X) && (p1.Y == p2.Y);
            }
            return false;
        }
        
        /// <summary>
        /// This operator determines whether two Points have the same location.
        /// </summary>
        /// <param name="p1">The first Point to be compared.</param>
        /// <param name="p2">The second Point to be compared.</param>
        /// <returns>
        /// True if the Points do not have the same location and the
        /// exact same type; otherwise, false.
        /// </returns>
        /// <seealso cref="Equals"/>
        /// <seealso cref="operator=="/>
        public static bool operator!=(Point p1, Point p2) => !(p1 == p2);
    }
}

Результирующий XML-код D.5.2

Ниже приведены выходные данные, созданные одним генератором документации при указании исходного кода для класса Point, показанного выше:

<?xml version="1.0"?>
<doc>
  <assembly>
    <name>Point</name>
  </assembly>
  <members>
    <member name="T:Graphics.Point">
    <summary>Class <c>Point</c> models a point in a two-dimensional
    plane.
    </summary>
    </member>
    <member name="M:Graphics.Point.#ctor">
      <summary>This constructor initializes the new Point to (0, 0).</summary>
    </member>
    <member name="M:Graphics.Point.#ctor(System.Int32,System.Int32)">
      <summary>
        This constructor initializes the new Point to
        (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
      </summary>
      <param name="xPosition">The new Point's x-coordinate.</param>
      <param name="yPosition">The new Point's y-coordinate.</param>
    </member>
    <member name="M:Graphics.Point.Move(System.Int32,System.Int32)">
      <summary>
        This method changes the point's location to
        the given coordinates.
        <see cref="M:Graphics.Point.Translate(System.Int32,System.Int32)"/>
      </summary>
      <param name="xPosition">The new x-coordinate.</param>
      <param name="yPosition">The new y-coordinate.</param>
      </member>
    <member name="M:Graphics.Point.Translate(System.Int32,System.Int32)">
      <summary>
        This method changes the point's location by
        the given x- and y-offsets.
        <example>For example:
        <code>
        Point p = new Point(3,5);
        p.Translate(-1,3);
        </code>
        results in <c>p</c>'s having the value (2,8).
        </example>
        <see cref="M:Graphics.Point.Move(System.Int32,System.Int32)"/>
      </summary>
      <param name="dx">The relative x-offset.</param>
      <param name="dy">The relative y-offset.</param>
    </member>
    <member name="M:Graphics.Point.Equals(System.Object)">
      <summary>
        This method determines whether two Points have the same location.
      </summary>
      <param name="o">
        The object to be compared to the current object.
      </param>
      <returns>
        True if the Points have the same location and they have
        the exact same type; otherwise, false.
      </returns>
      <seealso 
        cref="M:Graphics.Point.op_Equality(Graphics.Point,Graphics.Point)" />
      <seealso 
        cref="M:Graphics.Point.op_Inequality(Graphics.Point,Graphics.Point)"/>
    </member>
     <member name="M:Graphics.Point.ToString">
      <summary>
        Report a point's location as a string.
      </summary>
      <returns>
        A string representing a point's location, in the form (x,y),
        without any leading, training, or embedded whitespace.
      </returns>
     </member>
    <member name="M:Graphics.Point.op_Equality(Graphics.Point,Graphics.Point)">
      <summary>
        This operator determines whether two Points have the same location.
      </summary>
      <param name="p1">The first Point to be compared.</param>
      <param name="p2">The second Point to be compared.</param>
      <returns>
        True if the Points have the same location and they have
        the exact same type; otherwise, false.
      </returns>
      <seealso cref="M:Graphics.Point.Equals(System.Object)"/>
      <seealso
        cref="M:Graphics.Point.op_Inequality(Graphics.Point,Graphics.Point)"/>
    </member>
    <member
        name="M:Graphics.Point.op_Inequality(Graphics.Point,Graphics.Point)">
      <summary>
        This operator determines whether two Points have the same location.
      </summary>
      <param name="p1">The first Point to be compared.</param>
      <param name="p2">The second Point to be compared.</param>
      <returns>
        True if the Points do not have the same location and the
        exact same type; otherwise, false.
      </returns>
      <seealso cref="M:Graphics.Point.Equals(System.Object)"/>
      <seealso
        cref="M:Graphics.Point.op_Equality(Graphics.Point,Graphics.Point)"/>
      </member>
      <member name="M:Graphics.Point.Main">
        <summary>
          This is the entry point of the Point class testing program.
          <para>
            This program tests each method and operator, and
            is intended to be run after any non-trivial maintenance has
            been performed on the Point class.
          </para>
        </summary>
      </member>
      <member name="P:Graphics.Point.X">
        <value>
          Property <c>X</c> represents the point's x-coordinate.
        </value>
      </member>
      <member name="P:Graphics.Point.Y">
        <value>
          Property <c>Y</c> represents the point's y-coordinate.
        </value>
    </member>
  </members>
</doc>

Конец информативного текста.