Partilhar via


Anexo D Observações sobre a documentação

O presente anexo é informativo.

D.1 Generalidades

C# fornece um mecanismo para os programadores documentarem seu código usando uma sintaxe de comentário que contém texto XML. Em arquivos de código-fonte, comentários com uma determinada forma podem ser usados para direcionar uma ferramenta para produzir XML a partir desses comentários e dos elementos do código-fonte, que eles precedem. Os comentários que usam essa sintaxe são chamados de comentários de documentação. Eles devem preceder imediatamente um tipo definido pelo usuário (como uma classe, delegado ou interface) ou um membro (como um campo, evento, propriedade ou método). A ferramenta de geração XML é chamada de gerador de documentação. (Este gerador poderia ser, mas não precisa ser, o compilador C# em si.) A saída produzida pelo gerador de documentação é chamada de arquivo de documentação. Um arquivo de documentação é usado como entrada para um visualizador de documentação, uma ferramenta destinada a produzir algum tipo de exibição visual de informações de tipo e sua documentação associada.

Um compilador C# em conformidade não é necessário para verificar a sintaxe dos comentários da documentação; tais comentários são simplesmente comentários comuns. No entanto, um compilador em conformidade tem permissão para fazer essa verificação.

Esta especificação sugere um conjunto de tags padrão a serem usadas em comentários de documentação, mas o uso dessas tags não é necessário, e outras tags podem ser usadas se desejado, desde que as regras de XML bem formado sejam seguidas. Para implementações em C# direcionadas à CLI, ele também fornece informações sobre o gerador de documentação e o formato do arquivo de documentação. Nenhuma informação é fornecida sobre o visualizador de documentação.

D.2 Introdução

Comentários com uma determinada forma podem ser usados para direcionar uma ferramenta para produzir XML a partir desses comentários e dos elementos do código-fonte que eles precedem. Tais comentários são Single_Line_Comment s (§6.3.3) que começam com três barras (///), ou Delimited_Comments (§6.3.3) que começam com uma barra e dois asteriscos (/**). Eles devem preceder imediatamente um tipo definido pelo usuário ou um membro que eles anotam. As seções de atributos (§22.3) são consideradas parte das declarações, portanto, os comentários da documentação devem preceder os atributos aplicados a um tipo ou membro.

Para fins expositivos, o formato dos comentários do documento é mostrado abaixo como duas regras gramaticais: Single_Line_Doc_Comment e Delimited_Doc_Comment. No entanto, essas regras não fazem parte da gramática C#, mas representam formatos particulares de Single_Line_Comment e Delimited_Comment regras lexer, respectivamente.

Sintaxe:

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

Em um Single_Line_Doc_Comment, se houver um caractere Espaço em branco seguindo os /// caracteres em cada um dos Single_Line_Doc_Comments adjacentes ao Single_Line_Doc_Comment atual, esse caractere Espaço em branco não será incluído na saída XML.

Em um Delimited_Doc_Comment, se o primeiro caractere sem espaço em branco na segunda linha for um ASTERISCO e o mesmo padrão de caracteres opcionais de espaço em branco e um caractere ASTERISK for repetido no início de cada uma das linhas dentro do Delimited_Doc_Comment, os caracteres do padrão repetido não serão incluídos na saída XML. O padrão pode incluir caracteres de espaço em branco depois, bem como antes, do caractere ASTERISK .

Exemplo:

/// <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() {...}
}

O texto dentro dos comentários da documentação deve ser bem formado de acordo com as regras do XML (http://www.w3.org/TR/REC-xml). Se o XML estiver mal formado, um aviso será gerado e o arquivo de documentação conterá um comentário dizendo que um erro foi encontrado.

Embora os desenvolvedores sejam livres para criar seu próprio conjunto de tags, um conjunto recomendado é definido em §D.3. Algumas das tags recomendadas têm significados especiais:

  • A <param> tag é usada para descrever parâmetros. Se essa tag for usada, o gerador de documentação deve verificar se o parâmetro especificado existe e se todos os parâmetros estão descritos nos comentários da documentação. Se essa verificação falhar, o gerador de documentação emite um aviso.

  • O cref atributo pode ser anexado a qualquer tag para fornecer uma referência a um elemento de código. O gerador de documentação deve verificar se esse elemento de código existe. Se a verificação falhar, o gerador de documentação emitirá um aviso. Ao procurar um nome descrito em um cref atributo, o gerador de documentação deve respeitar a visibilidade do namespace de acordo com as instruções que aparecem no código-fonte. Para elementos de código que são genéricos, a sintaxe genérica normal (por exemplo, "List<T>") não pode ser usada porque produz XML inválido. Podem ser utilizados suportes em vez de suportes (por exemplo; "List{T}"), ou a sintaxe de escape XML pode ser usada (por exemplo, "List&lt;T&gt;").

  • A <summary> tag deve ser usada por um visualizador de documentação para exibir informações adicionais sobre um tipo ou membro.

  • A <include> tag inclui informações de um arquivo XML externo.

Observe cuidadosamente que o arquivo de documentação não fornece informações completas sobre o tipo e os membros (por exemplo, ele não contém nenhuma informação de tipo). Para obter essas informações sobre um tipo ou membro, o arquivo de documentação deve ser usado em conjunto com a reflexão sobre o tipo ou membro.

D.3.1 Generalidades

O gerador de documentação deve aceitar e processar qualquer tag que seja válida de acordo com as regras do XML. As tags a seguir fornecem a funcionalidade comumente usada na documentação do usuário. (Claro, outras tags são possíveis.)

Tag Referência Objetivo
<c> §D.3.2 Definir texto em uma fonte semelhante a um código
<code> §D.3.3 Definir uma ou mais linhas de código-fonte ou saída do programa
<example> §D.3.4 Indique um exemplo
<exception> §D.3.5 Identifica as exceções que um método pode gerar
<include> §D.3.6 Inclui XML de um arquivo externo
<list> §D.3.7 Criar uma lista ou tabela
<para> §D.3.8 Permitir que a estrutura seja adicionada ao texto
<param> §D.3.9 Descrever um parâmetro para um método ou construtor
<paramref> §D.3.10 Identificar que uma palavra é um nome de parâmetro
<permission> §D.3.11 Documentar a acessibilidade de segurança de um membro
<remarks> §D.3.12 Descrever informações adicionais sobre um tipo
<returns> §D.3.13 Descrever o valor de retorno de um método
<see> §D.3.14 Especificar um link
<seealso> §D.3.15 Gerar uma entrada Consulte também
<summary> §D.3.16 Descrever um tipo ou um membro de um tipo
<typeparam> §D.3.17 Descrever um parâmetro de tipo para um tipo ou método genérico
<typeparamref> §D.3.18 Identificar que uma palavra é um nome de parâmetro de tipo
<value> §D.3.19 Descrever uma propriedade

D.3.2 <c>

Essa tag fornece um mecanismo para indicar que um fragmento de texto dentro de uma descrição deve ser definido em uma fonte especial, como a usada para um bloco de código. Para linhas de código real, use <code> (§D.3.3).

Sintaxe:

<c>texto</c>

Exemplo:

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

Código D.3.3 <>

Essa tag é usada para definir uma ou mais linhas de código-fonte ou saída de programa em alguma fonte especial. Para pequenos fragmentos de código na narrativa, use <c> (§D.3.2).

Sintaxe:

<code>código fonte ou saída do programa</code>

Exemplo:

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)
    {
        ...
    }
}

Exemplo D.3.4 <>

Essa tag permite um código de exemplo dentro de um comentário para especificar como um método ou outro membro da biblioteca pode ser usado. Normalmente, isso também envolveria o uso da tag <code> (§D.3.3).

Sintaxe:

<example>descrição</example>

Exemplo:

Ver <code> (§D.3.3) para um exemplo.

D.3.5 <Exceção>

Essa tag fornece uma maneira de documentar as exceções que um método pode lançar.

Sintaxe:

<exception cref="Descrição do Membro"></exception>

em que

  • cref="membro" é o nome de um membro. O gerador de documentação verifica se o membro determinado existe e traduz o membro para o nome do elemento canônico no arquivo de documentação.
  • descrição é uma descrição das circunstâncias em que a exceção é lançada.

Exemplo:

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 <incluem>

Essa tag permite incluir informações de um documento XML externo ao arquivo de código-fonte. O arquivo externo deve ser um documento XML bem formado e uma expressão XPath é aplicada a esse documento para especificar qual XML desse documento deve ser incluído. A <include> marca é então substituída pelo XML selecionado do documento externo.

Sintaxe:

<include file="" path="Nome do arquivo XPath" />

em que

  • file="" filename é o nome de arquivo de um arquivo XML externo. O nome do arquivo é interpretado em relação ao arquivo que contém a marca include.
  • path="xpath" é uma expressão XPath que seleciona parte do XML no arquivo XML externo.

Exemplo:

Se o código-fonte continha uma declaração como:

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

e o ficheiro externo "docs.xml" tinha o seguinte conteúdo:

<?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>

em seguida, a mesma documentação é saída como se o código-fonte contivesse:

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

D.3.7 <Lista>

Essa tag é usada para criar uma lista ou tabela de itens. Ele pode conter um <listheader> bloco para definir a linha de título de uma tabela ou lista de definições. (Ao definir uma tabela, apenas uma entrada para termo no título precisa ser fornecida.)

Cada item da lista é especificado com um <item> bloco. Ao criar uma lista de definições, tanto o termo quanto a descrição devem ser especificados. No entanto, para uma tabela, lista com marcadores ou lista numerada, apenas a descrição precisa ser especificada.

Sintaxe:

<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>

em que

  • termo é o termo a definir, cuja definição está na descrição.
  • Descrição é um item em um marcador ou lista numerada, ou a definição de um termo.

Exemplo:

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>

Esta etiqueta destina-se a ser utilizada dentro de outras etiquetas, tais como <summary> (§D.3.16) ou <returns> (§D.3.13), e permite adicionar estrutura ao texto.

Sintaxe:

<para>Conteúdo</para>

em que

  • conteúdo é o texto do parágrafo.

Exemplo:

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>

Essa tag é usada para descrever um parâmetro para um método, construtor ou indexador.

Sintaxe:

<param name="Descrição do nome"></param>

em que

  • name é o nome do parâmetro.
  • description é uma descrição do parâmetro.

Exemplo:

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>

Essa tag é usada para indicar que uma palavra é um parâmetro. O arquivo de documentação pode ser processado para formatar esse parâmetro de alguma forma distinta.

Sintaxe:

<paramref name="Designação"/>

em que

  • name é o nome do parâmetro.

Exemplo:

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 <autorização>

Essa tag permite que a acessibilidade de segurança de um membro seja documentada.

Sintaxe:

<permission cref="Descrição do Membro"></permission>

em que

  • membro é o nome de um membro. O gerador de documentação verifica se o elemento de código fornecido existe e traduz o membro para o nome do elemento canônico no arquivo de documentação.
  • Descrição é uma descrição do acesso ao membro.

Exemplo:

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

D.3.12 <Observações>

Essa tag é usada para especificar informações adicionais sobre um tipo. Utilizar <summary> (§D.3.16) para descrever o próprio tipo e os membros de um tipo.

Sintaxe:

<remarks>descrição</remarks>

em que

  • descrição é o texto da observação.

Exemplo:

/// <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 <devoluções>

Essa tag é usada para descrever o valor de retorno de um método.

Sintaxe:

<returns>descrição</returns>

em que

  • description é uma descrição do valor de retorno.

Exemplo:

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 <Ver>

Essa tag permite que um link seja especificado no texto. Utilizar <seealso> (§D.3.15) para indicar o texto que deve aparecer numa subcláusula Consulte Também .

Sintaxe:

<see cref="palavra-chave url" langword="do membro" href="" />

em que

  • membro é o nome de um membro. O gerador de documentação verifica se o elemento de código fornecido existe e altera o membro para o nome do elemento no arquivo de documentação gerado.
  • URL é uma referência a uma fonte externa.
  • langword é uma palavra a ser destacada de alguma forma.

Exemplo:

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 <ver também>

Essa tag permite que uma entrada seja gerada para a subcláusula Consulte também . Use <see> (§D.3.14) para especificar um link a partir do texto.

Sintaxe:

<seealso cref="url do membro" href="" />

em que

  • membro é o nome de um membro. O gerador de documentação verifica se o elemento de código fornecido existe e altera o membro para o nome do elemento no arquivo de documentação gerado.
  • URL é uma referência a uma fonte externa.

Exemplo:

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 <Resumo>

Essa tag pode ser usada para descrever um tipo ou um membro de um tipo. Utilizar <remarks> (§D.3.12) para especificar informações adicionais sobre o tipo ou membro.

Sintaxe:

<summary>descrição</summary>

em que

  • Descrição é um resumo do tipo ou membro.

Exemplo:

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 <tipoparam>

Essa tag é usada para descrever um parâmetro de tipo para um tipo ou método genérico.

Sintaxe:

<typeparam name="Descrição do nome"></typeparam>

em que

  • name é o nome do parâmetro type.
  • description é uma descrição do parâmetro type.

Exemplo:

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

D.3.18 <Tipo paramref>

Essa tag é usada para indicar que uma palavra é um parâmetro type. O arquivo de documentação pode ser processado para formatar esse parâmetro de tipo de alguma forma distinta.

Sintaxe:

<typeparamref name="Designação"/>

em que

  • name é o nome do parâmetro type.

Exemplo:

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)
    {
        ...
    }
}

Valor D.3.19 <>

Essa tag permite que uma propriedade seja descrita.

Sintaxe:

<value>Descrição do imóvel</value>

em que

  • Descrição da propriedade é uma descrição da propriedade.

Exemplo:

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

D.4 Tratamento do processo de documentação

D.4.1 Generalidades

As informações a seguir destinam-se a implementações em C# direcionadas à CLI.

O gerador de documentação gera uma cadeia de caracteres de ID para cada elemento no código-fonte que é marcado com um comentário de documentação. Essa cadeia de caracteres de ID identifica exclusivamente um elemento de origem. Um visualizador de documentação pode usar uma cadeia de caracteres de ID para identificar o item correspondente ao qual a documentação se aplica.

O arquivo de documentação não é uma representação hierárquica do código-fonte; em vez disso, é uma lista simples com uma cadeia de caracteres de ID gerada para cada elemento.

D.4.2 Formato da cadeia de identificação

O gerador de documentação observa as seguintes regras quando gera as cadeias de caracteres de ID:

  • Nenhum espaço em branco é colocado na cadeia de caracteres.

  • A primeira parte da cadeia de caracteres identifica o tipo de membro que está sendo documentado, através de um único caractere seguido por dois pontos. São definidos os seguintes tipos de membros:

    Personagem Descrição
    E Evento
    F Campo
    Seg Método (incluindo construtores, finalizadores e operadores)
    N Espaço de Nomes
    P Propriedade (incluindo indexadores)
    T Tipo (como classe, delegado, enum, interface e struct)
    ! Cadeia de erro; O restante da cadeia de caracteres fornece informações sobre o erro. Por exemplo, o gerador de documentação gera informações de erro para links que não podem ser resolvidos.
  • A segunda parte da cadeia de caracteres é o nome totalmente qualificado do elemento, começando na raiz do namespace. O nome do elemento, seu(s) tipo(s) de delimitação e o namespace são separados por pontos. Se o nome do item em si tiver pontos, eles serão substituídos por # (U+0023) caracteres. (Supõe-se que nenhum elemento tenha esse caractere em seu nome.) Os argumentos de tipo no nome totalmente qualificado, para quando um membro implementa explicitamente um membro de uma interface genérica, são codificados substituindo os caracteres "<" e ">" que os cercam pelos caracteres "{" e "}".

  • Para métodos e propriedades com argumentos, segue-se a lista de argumentos, entre parênteses. Para aqueles sem argumentos, os parênteses são omitidos. Os argumentos são separados por vírgulas. A codificação de cada argumento é a mesma que uma assinatura CLI, da seguinte forma:

    • Os argumentos são representados pelo nome da documentação, que se baseia no nome totalmente qualificado, modificado da seguinte forma:
      • Os argumentos que representam tipos genéricos têm um caractere "'" anexado seguido pelo número de parâmetros de tipo
      • Os argumentos com o in, out ou ref modificador têm um seguinte nome de @ tipo. Os argumentos passados por valor ou via params não têm notação especial.
      • Os argumentos que são matrizes são representados como [ tamanho , inferior : ... ,limite : inferior tamanho ] onde o número de vírgulas é a ordem menos um, e os limites inferiores e o tamanho de cada dimensão, se conhecidos, são representados em decimais. Se um limite inferior ou tamanho não for especificado, ele será omitido. Se o limite inferior e o tamanho de uma determinada dimensão forem omitidos, o ":" também será omitido. As matrizes irregulares são representadas por um "[]" por nível. As matrizes unidimensionais omitem o limite inferior quando o limite inferior é 0 (o padrão) (§17.1).
      • Argumentos que têm tipos de ponteiro diferentes são void representados usando um * seguinte o nome do tipo. Um void ponteiro é representado usando um nome de tipo de System.Void.
      • Os argumentos que se referem a parâmetros de tipo genéricos definidos em tipos são codificados usando o caractere "`" seguido pelo índice baseado em zero do parâmetro type.
      • Os argumentos que usam parâmetros de tipo genéricos definidos em métodos usam um backtick duplo "``" em vez do "`" usado para tipos.
      • Os argumentos que se referem a tipos genéricos construídos são codificados usando o tipo genérico, seguido por "{", seguido por uma lista separada por vírgulas de argumentos de tipo, seguido por "}".

D.4.3 Exemplos de cadeias de identificação

Os exemplos a seguir mostram um fragmento de código C#, juntamente com a cadeia de caracteres de ID produzida a partir de cada elemento de origem capaz de ter um comentário de documentação:

Os tipos são representados usando seu nome totalmente qualificado, aumentado com informações genéricas:

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> { ... }
    }
}

IDs:

"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"

Os campos são representados pelo seu nome totalmente qualificado.

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;
    }
}

IDs:

"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"

Construtores

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

IDs:

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

Finalizadores

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

IDs:

"M:Acme.Widget.Finalize"

Metodologia

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) { ... } 
    }
}

IDs:

"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)"

Propriedades e indexadores

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 { ... } }
    }
}

IDs:

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

Eventos

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

IDs:

"E:Acme.Widget.AnEvent"

Operadores unários

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

IDs:

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

O conjunto completo de nomes de funções de operador unário usado é o seguinte: op_UnaryPlus, op_UnaryNegation, op_LogicalNot, op_OnesComplement, op_Increment, op_Decrement, op_True, e op_False.

Operadores binários

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

IDs:

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

O conjunto completo de nomes de funções de operadores binários usados é o seguinte: op_Addition, op_Subtraction, op_Multiply, op_Division, op_ExclusiveOrop_BitwiseAndop_LeftShiftop_RightShiftop_Equalityop_BitwiseOrop_Modulusop_LessThanop_LessThanOrEqualop_Inequalityop_GreaterThane .op_GreaterThanOrEqual

Os operadores de conversão têm um "~" à direita seguido do tipo de retorno. Quando a origem ou o destino de um operador de conversão é um tipo genérico, os caracteres "<" e "">" são substituídos pelos caracteres "{" e "}", respectivamente.

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

IDs:

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

D.5 Um exemplo

D.5.1 Código fonte C#

O exemplo a seguir mostra o código-fonte de uma classe 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);
    }
}

D.5.2 XML resultante

Aqui está a saída produzida por um gerador de documentação quando dado o código-fonte para a classe Point, mostrado acima:

<?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>

Fim do texto informativo.