Anexo D Observações sobre a documentação
Este anexo é informativo.
D.1 Geral
O 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 de XML é chamada de gerador de documentação. (Esse gerador pode ser, mas não precisa ser, o próprio compilador C#.) 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 formadas sejam seguidas. Para implementações 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 de 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 atributo (§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 específicos de regras Single_Line_Comment e Delimited_Comment 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 de espaço em branco após os ///
caracteres em cada um dos Single_Line_Doc_Comments adjacentes ao Single_Line_Doc_Comment atual, esse caractere de espaço em branco não será incluído na saída XML.
Em um Delimited_Doc_Comment, se o primeiro caractere que não for de espaço em branco na segunda linha for um ASTERISCO e o mesmo padrão de caracteres de espaço em branco opcionais e um caractere ASTERISCO 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 após, bem como antes, do caractere ASTERISCO .
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 informando 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 marcas recomendadas têm significado especial:
A marca
<param>
é usada para descrever parâmetros. Se essa tag for usada, o gerador de documentação deverá 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 emitirá um aviso.O atributo
cref
pode ser anexado a qualquer marca 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 umcref
atributo, o gerador de documentação deve respeitar a visibilidade do namespace de acordo com as instruções using que aparecem no código-fonte. Para elementos de código genéricos, a sintaxe genérica normal (por exemplo, "List<T>
") não pode ser usada porque produz XML inválido. Aparelhos podem ser usados em vez de colchetes (por exemplo; "List{T}
"), ou a sintaxe de escape XML pode ser usada (por exemplo, "List<T>
").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 Tags recomendadas
D.3.1 Generalidades
O gerador de documentação deve aceitar e processar qualquer tag válida de acordo com as regras de XML. As seguintes marcas fornecem as funcionalidades geralmente usadas na documentação do usuário. (Claro, outras tags são possíveis.)
Marca | Referência | Finalidade |
---|---|---|
<c> |
§D.3.2 | Definir texto em uma fonte semelhante a um código |
<code> |
§D.3.3 | Defina 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 lançar |
<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 | Identifique 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 retornado 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>
text</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)
{
...
}
}
D.3.4 <exemplo>
Essa tag permite que o código de exemplo dentro de um comentário especifique 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:
Veja <code>
(§D.3.3) para um exemplo.
Exceção D.3.5 <>
Essa tag fornece uma maneira de documentar as exceções que um método pode gerar.
Sintaxe:
<exception cref="
Descrição do membro">
</exception>
onde
cref="
member"
é o nome de um membro. O gerador de documentação verifica se o membro fornecido existe e converte o membro para o nome do elemento canônico no arquivo de documentação.- description é 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 incluir. A <include>
tag é então substituída pelo XML selecionado do documento externo.
Sintaxe:
<include file="
Nome do arquivo" path="
XPath" />
onde
file="
filename"
é o nome de um arquivo XML externo. O nome do arquivo é interpretado em relação ao arquivo que contém a marca de inclusão.path="
xpath"
é uma expressão XPath que seleciona parte do XML no arquivo XML externo.
Exemplo:
Se o código-fonte contiver uma declaração como:
/// <include file="docs.xml" path='extradoc/class[@name="IntList"]/*' />
public class IntList { ... }
e o arquivo 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 é gerada como se o código-fonte contivesse:
/// <summary>
/// Contains a list of integers.
/// </summary>
public class IntList { ... }
Lista D.3.7 <>
Essa tag é usada para criar uma lista ou tabela de itens. Ele pode conter um <listheader>
bloco para definir a linha de cabeçalho de uma tabela ou lista de definições. (Ao definir uma tabela, apenas uma entrada para o termo no título precisa ser fornecida.)
Cada item na lista é especificado com um bloco <item>
. Ao criar uma lista de definições, o termo e a descrição devem ser especificados. No entanto, para uma tabela, lista com marcadores ou lista numerada, somente 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>
onde
- termo é o termo a definir, cuja definição está na descrição.
- description é 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>
Essa tag é para uso dentro de outras tags, como <summary>
(§D.3.16) ou <returns>
(§D.3.13), e permite que a estrutura seja adicionada ao texto.
Sintaxe:
<para>
content</para>
onde
- content é 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()
{
...
}
}
Parâmetro D.3.9 <>
Essa marca é usada para descrever um parâmetro para um método, construtor ou indexador.
Sintaxe:
<param name="
nome">
descrição</param>
onde
- 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 maneira distinta.
Sintaxe:
<paramref name="
name"/>
onde
- 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>
onde
- member é o nome de um membro. O gerador de documentação verifica se o elemento de código fornecido existe e converte o membro para o nome do elemento canônico no arquivo de documentação.
- description é 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 extras sobre um tipo. Use <summary>
(§D.3.16) para descrever o tipo em si e os membros de um tipo.
Sintaxe:
<remarks>
descrição</remarks>
onde
- description é 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>
onde
- description é uma descrição do valor retornado.
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. Use <seealso>
(§D.3.15) para indicar o texto que deve aparecer em uma subcláusula Consulte também .
Sintaxe:
<see cref="
palavra-chave de url" langword="
do membro" href="
" />
onde
- member é 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 de dentro do texto.
Sintaxe:
<seealso cref="
URL do membro" href="
" />
onde
- member é 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 marca pode ser usada para descrever um tipo ou um membro de um tipo. Use <remarks>
(§D.3.12) para especificar informações extras sobre o tipo ou barra.
Sintaxe:
<summary>
descrição</summary>
onde
- description é 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 <typeparam>
Essa tag é usada para descrever um parâmetro de tipo para um tipo ou método genérico.
Sintaxe:
<typeparam name="
nome">
descrição</typeparam>
onde
- name é o nome do parâmetro de tipo.
- description é uma descrição do parâmetro de tipo.
Exemplo:
/// <summary>A generic list class.</summary>
/// <typeparam name="T">The type stored by the list.</typeparam>
public class MyList<T>
{
...
}
D.3.18 <typeparamref>
Essa marca é usada para indicar que uma palavra é um parâmetro de tipo. O arquivo de documentação pode ser processado para formatar esse parâmetro de tipo de alguma maneira distinta.
Sintaxe:
<typeparamref name="
name"/>
onde
- name é o nome do parâmetro de tipo.
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)
{
...
}
}
D.3.19 <Valor>
Essa tag permite que uma propriedade seja descrita.
Sintaxe:
<value>
Descrição do Imóvel</value>
onde
- A 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 Processamento do arquivo de documentação
D.4.1 Generalidades
As informações a seguir destinam-se a implementações de 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 string 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 string de ID gerada para cada elemento.
D.4.2 Formato de cadeia de caracteres de ID
O gerador de documentação observa as seguintes regras ao gerar 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, por meio de um único caractere seguido por dois-pontos. Os seguintes tipos de membros são definidos:
Caractere Descrição E Evento F Campo M Método (incluindo construtores, finalizadores e operadores) N Namespace P Propriedade (incluindo indexadores) T Tipo (como classe, delegado, enumeração, interface e struct) ! Cadeia de caracteres 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, seus tipos delimitadores e namespace são separados por pontos. Se o nome do item em si tiver pontos, eles serão substituídos por caracteres # (U+0023). (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 ">
" ao redor deles pelos caracteres "{
" e "}
".Para métodos e propriedades com argumentos, a lista de argumentos segue, 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 de uma assinatura CLI, da seguinte maneira:
- Os argumentos são representados pelo nome da documentação, que se baseia no nome totalmente qualificado, modificado da seguinte maneira:
- Os argumentos que representam tipos genéricos têm um caractere "
'
" acrescentado seguido pelo número de parâmetros de tipo - Os argumentos com o
in
modificador ,out
ouref
têm um@
nome de tipo seguinte. Os argumentos passados por valor ou viaparams
não têm notação especial. - Os argumentos que são matrizes são representados como
[
tamanho,
de limite:
inferior ...,
limite:
inferior tamanho]
onde o número de vírgulas é a classificação menos um, e os limites inferiores e o tamanho de cada dimensão, se conhecidos, são representados em decimal. Se um limite inferior ou tamanho não for especificado, ele será omitido. Se o limite inferior e o tamanho de uma dimensão específica forem omitidos, o ":
" também será omitido. 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). - Os argumentos que têm tipos de ponteiro diferentes de
void
são representados usando um*
nome de tipo seguinte. Umvoid
ponteiro é representado usando um nome de tipo deSystem.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 de tipo. - Os argumentos que usam parâmetros de tipo genéricos definidos em métodos usam um acento grave 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 "}
".
- Os argumentos que representam tipos genéricos têm um caractere "
- Os argumentos são representados pelo nome da documentação, que se baseia no nome totalmente qualificado, modificado da seguinte maneira:
D.4.3 Exemplos de string de ID
Os exemplos a seguir mostram um fragmento de código C#, juntamente com a cadeia de caracteres de ID produzida 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 por 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"
Métodos
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ção de operador unário usados é 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 operador binário usados é o seguinte: , , , op_BitwiseAnd
op_GreaterThan
op_Equality
op_LessThanOrEqual
op_ExclusiveOr
op_LeftShift
op_RightShift
op_LessThan
op_GreaterThanOrEqual
op_Modulus
op_Inequality
op_Division
op_BitwiseOr
op_Multiply
op_Subtraction
op_Addition
Os operadores de conversão têm um "~
" à direita seguido pelo 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 fornecido 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.
ECMA C# draft specification