Processamento de arquivo de documentação XML
O compilador gera uma cadeia de identificação para cada constructo no seu código marcado para gerar a documentação. Para obter mais informações, confira Marcas recomendadas para comentários da documentação. A cadeia de identificação identifica exclusivamente o constructo. Programas que processam o arquivo XML podem usar a cadeia de ID para identificar o item correspondente de metadados ou de reflexão do .NET Framework ao qual a documentação se aplica.
O arquivo XML não é uma representação hierárquica do código; é uma lista plana com uma ID gerada para cada elemento.
O compilador observa as seguintes regras quando gera as cadeias de identificação:
Nenhum espaço em branco é colocado na cadeia de caracteres.
A primeira parte da cadeia de identificação identifica o tipo de membro que está sendo identificado, com um único caractere seguido por dois-pontos. São usados os seguintes tipos de membro:
Caractere Descrição N Namespace
Não é possível adicionar comentários da documentação a um namespace, mas é possível adicionar referências cref a um namespace.T Tipo: classe, interface, struct, enumeração, delegado D Typedef F Campo P Propriedade (incluindo indexadores ou outras propriedades indexadas) M Método (incluindo métodos especiais como construtores, operadores e assim por diante) E Evento ! Cadeia de caracteres de erro
O restante da cadeia de caracteres fornece informações sobre o erro. O compilador do MSVC 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 item, iniciando na raiz do namespace. O nome do item, seus tipos delimitadores e o namespace são separados por pontos. Se o nome do próprio item tiver pontos, eles serão substituídos pelo sustenido ('#'). Supõe-se que nenhum item tem um sustenido diretamente em seu nome. Por exemplo, o nome totalmente qualificado do construtor
String
seriaSystem.String.#ctor
.Para propriedades e métodos, se houver argumentos para o método, seguirá a lista de argumentos entre parênteses. Se não houver nenhum argumento, não haverá parênteses. Os argumentos são separados por vírgulas. Cada argumento é codificado da mesma forma que é codificado em uma assinatura do .NET Framework:
Tipos base. Tipos regulares (
ELEMENT_TYPE_CLASS
ouELEMENT_TYPE_VALUETYPE
) são representados como o nome totalmente qualificado do tipo.Tipos intrínsecos (por exemplo,
ELEMENT_TYPE_I4
,ELEMENT_TYPE_OBJECT
,ELEMENT_TYPE_STRING
,ELEMENT_TYPE_TYPEDBYREF
eELEMENT_TYPE_VOID
) são representados como o nome totalmente qualificado do tipo completo correspondente, por exemplo,System.Int32
ouSystem.TypedReference
.ELEMENT_TYPE_PTR
é representado como um '*
' após o tipo modificado.ELEMENT_TYPE_BYREF
é representado como um '@
' após o tipo modificado.ELEMENT_TYPE_PINNED
é representado como um '^
' após o tipo modificado. O compilador do MSVC nunca gera esse elemento.ELEMENT_TYPE_CMOD_REQ
é representado como um '|
' e o nome totalmente qualificado da classe do modificador, após o tipo modificado. O compilador do MSVC nunca gera esse elemento.ELEMENT_TYPE_CMOD_OPT
é representado como um '!
' e o nome totalmente qualificado da classe do modificador, após o tipo modificado.ELEMENT_TYPE_SZARRAY
é representado como "[]
" após o tipo de elemento da matriz.ELEMENT_TYPE_GENERICARRAY
é representado como "[?]
" após o tipo de elemento da matriz. O compilador do MSVC nunca gera esse elemento.ELEMENT_TYPE_ARRAY
é representado como[
lower bound:
size,
lower bound:
size]
em que o número de vírgulas é a classificação -1, e o limite inferior e o tamanho de cada dimensão, se conhecidos, são representados no formato decimal. Se um limite inferior ou tamanho não for especificado, ele será omitido. Se o limite inferior e o tamanho forem omitidos para uma determinada dimensão, o ':
' também será omitido. Por exemplo, uma matriz bidimensional com 1 como o limite inferior e os tamanhos não especificados é representada como[1:,1:]
.ELEMENT_TYPE_FNPTR
é representado como "=FUNC:type
(signature)", em quetype
é o tipo de retorno e assinatura são os argumentos do método. Se não houver nenhum argumento, os parênteses serão omitidos. O compilador do MSVC nunca gera esse elemento.
Os seguintes componentes de assinatura não são representados, porque nunca são usados para diferenciar métodos sobrecarregados:
Convenção de chamada
Tipo de retorno
ELEMENT_TYPE_SENTINEL
Somente para operadores de conversão, o valor retornado do método é codificado como um '
~
' seguido pelo tipo de retorno, conforme codificado anteriormente.Para tipos genéricos, o nome do tipo será seguido por um backtick e, em seguida, um número que indica o número de parâmetros de tipo genérico. Por exemplo,
<member name="T:MyClass`2">
O exemplo mostra um tipo definido como
public class MyClass<T, U>
.Para métodos que aceitam tipos genéricos como parâmetros, os parâmetros de tipo genérico são especificados como números precedidos por caracteres de acento grave (por exemplo, `0, `1). Cada número representa uma posição de matriz com base em zero para parâmetros genéricos do tipo.
Exemplo
Os exemplos a seguir mostram como as cadeias de identificação de uma classe e seus membros são geradas.
// xml_id_strings.cpp
// compile with: /clr /doc /LD
///
namespace N {
// "N:N"
/// <see cref="System" />
// <see cref="N:System"/>
ref class X {
// "T:N.X"
protected:
///
!X(){}
// "M:N.X.Finalize", destructor's representation in metadata
public:
///
X() {}
// "M:N.X.#ctor"
///
static X() {}
// "M:N.X.#cctor"
///
X(int i) {}
// "M:N.X.#ctor(System.Int32)"
///
~X() {}
// "M:N.X.Dispose", Dispose function representation in metadata
///
System::String^ q;
// "F:N.X.q"
///
double PI;
// "F:N.X.PI"
///
int f() { return 1; }
// "M:N.X.f"
///
int bb(System::String ^ s, int % y, void * z) { return 1; }
// "M:N.X.bb(System.String,System.Int32@,System.Void*)"
///
int gg(array<short> ^ array1, array< int, 2 >^ IntArray) { return 0; }
// "M:N.X.gg(System.Int16[], System.Int32[0:,0:])"
///
static X^ operator+(X^ x, X^ xx) { return x; }
// "M:N.X.op_Addition(N.X,N.X)"
///
property int prop;
// "M:N.X.prop"
///
property int prop2 {
// "P:N.X.prop2"
///
int get() { return 0; }
// M:N.X.get_prop2
///
void set(int i) {}
// M:N.X.set_prop2(System.Int32)
}
///
delegate void D(int i);
// "T:N.X.D"
///
event D ^ d;
// "E:N.X.d"
///
ref class Nested {};
// "T:N.X.Nested"
///
static explicit operator System::Int32 (X x) { return 1; }
// "M:N.X.op_Explicit(N.X!System.Runtime.CompilerServices.IsByValue)~System.Int32"
};
}