Aunque en principio los atributos
de las etiquetas no tienen ningún significado predeterminado para el
compilador, hay una excepción: el atributo cref siempre va a tener un significado concreto
consistente en forzarlo a comprobar cuando vaya a generar la documentación si
existe el elemento cuyo nombre indique y, si no es así, hacerle producir un
mensaje de aviso (su nombre viene de “check reference”)
Los elementos especificados en cref suelen
indicarse mediante calificación completa, y pueden ser tanto nombres de
miembros como de espacios de nombres. En el Tema
6: Espacios de Nombres ya se explicó como indicar así nombres de tipos y de
espacios de nombres, mientras que para indicar el de miembros de tipos basta
escribir el nombre completo del tipo donde estén definidos seguido de un punto
tras el cual, dependiendo del tipo de miembro del que se trate, se escribiría :
·
Si es un campo,
propiedad, evento o tipo interno, su nombre.
·
Si es un método,
su nombre seguido de los nombres completos de los tipos de sus parámetros
separados mediante comas y entre paréntesis. Estos nombres de tipos de
parámetros llevan un carácter @ concatendo al final en los parámetros ref u
out,
un carácter *
al final en los que sean de tipos
punteros, un símbolo [] por cada nivel de anidación al final de los
que sean tablas unidimensionales, y una estructura de la forma [0:,0:] al final de los que sean tablas
bidimensionales (para tablas de más dimensiones simplemente se irían añadiendo
los bloques ,0:
apropiados)
·
Si es un indizador,
el identificador Item
seguido de la lista de tipos de sus índices como si de los
parámetros de un método se tratase
·
Si es un constructor
de objeto, el identificador #ctor seguido de la lista de tipos de sus
parámetros como si de un método normal se tratase. Si el constructor fuese de
tipos entonces el identificador usado sería #cctor
·
Si es un destructor,
el identificador Finalize.
·
Si es un operador,
el identificador que represente a ese
operador segudio de la lista de los tipos de sus operandos como si fuesen los
parámetros de un método normal. En la Tabla 8 se resumen los identificador que se dan a cada
operador:
|
Operador
|
Identificador
|
|
Operador
|
Identficador
|
|
+
|
op_Addition
|
|
&
|
op_BitwiseAnd
|
|
-
|
op_Substraction
|
|
|
|
op_BitwiseOr
|
|
*
|
op_Multiply
|
|
^
|
op_ExclusiveOr
|
|
/
|
op_Division
|
|
~
|
op_OnesComplement
|
|
%
|
op_Modulus
|
|
<<
|
op_LeftShift
|
|
<
|
op_LessThan
|
|
>>
|
op_RightShift
|
|
>
|
op_GreaterThan
|
|
true
|
op_True
|
|
>=
|
op_GreaterThanOrEqual
|
|
false
|
op_False
|
|
<=
|
op_LowerThanOrEqual
|
|
++
|
op_Increment
|
|
==
|
op_Equality
|
|
--
|
op_Decrement
|
|
!=
|
op_Inequality
|
|
Conversión explícita
|
Op_Explict
|
|
!
|
op_LogicalNot
|
|
Conversión implícita
|
Op_Implicit
|
Tabla 8: Nombres
dados a operadores en documentación XML
En el caso de
los operadores de conversión, tras la lista de parámetros se incluye
adicionalmente un carácter ~ seguido del tipo de retorno del operador.
Para que se entienda mejor la
forma en que se han de dar valores a cref, a continuación se muestra un fragmento de
código de ejemplo en el que junto a cada definición se ha escrito un comentario
con el valor que habría que darle a cref para referenciarla:
// cref=”Espacio”
namespace
Espacio
{
//
cref=”Espacio.Clase”
class
Clase
{
//
cref=”Espacio.Clase.Campo”
int
Campo;
//
cref=”Espacio.Clase.Propiedad”
int Propiedad
{
set {} }
//
cref=”Espacio.Clase.EstructuraInterna”
struct EstructuraInterna {}
//
cref=”Espacio.Clase.DelegadoInterno”
public
delegate int DelegadoInterno(string s, float f);
// cref
=”Espacio.Clase.Evento”
public event DelegadoInterno Evento;
//
cref=”Espacio.Clase.Metodo(System.Int32, System.Int32@,
// System.Int32*, System.Int32@,
// System.Int32[][], System.Int32[0:, 0:,
0:])”
int
Metodo(int a, out int b, int * c, ref
d, int[][] e, int[,,] f)
{return
1;}
//
cref=”Espacio.Clase.Item(System.String)”
int
this[string s]
{
set {} }
//
cref=”Espacio.Clase.#ctor”
Clase(int
a)
{}
//
cref=”Espacio.Clase.#cctor”
static Clase(int a)
{}
//
cref=”Espacio.Clase.Finalize”
~X()
{}
//
cref=”Espacio.Clase.op_Addition(Espacio.Clase, Espacio.Clase)”
public static int operator +(Clase
operando1, Clase operando2)
{
return 1; }
//
cref=”Espacio.Clase.op_Explicit (Espacio.Clase)~System.Int32”
public static explicit operator
int(Clase fuente)
{
return 1; }
}
}
En realidad no es siempre
necesario usar califiación completa en el valor de cref. Si se referencia
a un tipo desde la misma definición de espacio de nombres desde donde se le
definió o que importa su espacio de nombres, no es necesario incluir dicho
espacio en la referencia; y si se referencia a un miembro desde el el mismo
tipo donde se definió, no es necesario incluir ni el nombre del tipo ni el de
su espacio de nombres.