Comentarios de documentación

Los comentarios de documentación tienen un formato especial en el origen que se puede analizar para generar documentación sobre el código al que se adjuntan. El formato básico para los comentarios de documentación es XML. Cuando el código de compilación con comentarios de documentación, el compilador puede emitir opcionalmente un archivo XML que represente la suma total de los comentarios de documentación en el origen. A continuación, otras herramientas pueden usar este archivo XML para generar documentación impresa o en línea.

En este capítulo se describen los comentarios de documentos y las etiquetas XML recomendadas para usarlas con comentarios de documento.

Formato de comentario de documentación

Los comentarios del documento son comentarios especiales que comienzan por ''', tres comillas simples. Deben preceder inmediatamente al tipo (como una clase, un delegado o una interfaz) o un miembro de tipo (como un campo, evento, propiedad o método) que documentan. Un comentario de documento sobre una declaración de método parcial se reemplazará por el comentario del documento en el método que proporciona su cuerpo, si hay uno. Todos los comentarios de documento adyacentes se anexan juntos para generar un único comentario de documento. Si hay un carácter de espacio en blanco que sigue a los ''' caracteres, ese carácter de espacio en blanco no se incluye en la concatenación. Por ejemplo:

''' <remarks>
''' Class <c>Point</c> models a point in a two-dimensional plane.
''' </remarks>
Public Class Point 
   ''' <remarks>
   ''' Method <c>Draw</c> renders the point.
   ''' </remarks>
   Sub Draw()
   End Sub
End Class

Los comentarios de documentación deben tener un formato XML correcto según https://www.w3.org/TR/REC-xml. Si el XML no tiene un formato correcto, se genera una advertencia y el archivo de documentación contendrá un comentario que indica que se encontró un error.

Aunque los desarrolladores pueden crear su propio conjunto de etiquetas, se define un conjunto recomendado en la sección siguiente. Algunas de las etiquetas recomendadas tienen significados especiales:

  • La etiqueta <param> se usa para describir parámetros. El parámetro especificado por una <param> etiqueta debe existir y todos los parámetros del miembro de tipo deben describirse en el comentario de documentación. Si alguna de las dos condiciones no es true, el compilador emite una advertencia.

  • El atributo cref se puede asociar a cualquier etiqueta para proporcionar una referencia a un elemento de código. El elemento de código debe existir; en tiempo de compilación, el compilador reemplaza el nombre por la cadena id. que representa al miembro. Si el elemento de código no existe, el compilador emite una advertencia. Al buscar un nombre descrito en un cref atributo, el compilador respeta las instrucciones Imports que aparecen dentro del archivo de origen contenedor.

  • La etiqueta <summary> está destinada a ser usada por un visor de documentación para mostrar información adicional sobre un tipo o miembro.

Tenga en cuenta que el archivo de documentación no proporciona información completa sobre un tipo y miembros, solo lo que se incluye en los comentarios del documento. Para obtener más información sobre un tipo o miembro, el archivo de documentación debe usarse junto con la reflexión sobre el tipo o miembro real.

El generador de documentación debe aceptar y procesar cualquier etiqueta que sea válida según las reglas de XML. Las etiquetas siguientes proporcionan funcionalidades usadas habitualmente en la documentación del usuario:

<c> Establece texto en una fuente similar a código

<code> Establece una o varias líneas de código fuente o salida de programa en una fuente similar a código

<example> Indica un ejemplo

<exception> Identifica las excepciones que un método puede producir

<include> Incluye un documento XML externo

<list> Crea una lista o tabla

<para> Permite agregar la estructura al texto

<param> Describe un parámetro para un método o constructor

<paramref> Identifica que una palabra es un nombre de parámetro.

<permission> Documenta la accesibilidad de seguridad de un miembro

<remarks> Describe un tipo

<returns> Describe el valor devuelto de un método

<see> Especifica un vínculo

<seealso> Genera una entrada See Also

<summary> Describe un miembro de un tipo

<typeparam> Describe un parámetro de tipo

<value> Describe una propiedad

<c>

Esta etiqueta especifica que un fragmento de texto dentro de una descripción debe usar una fuente como la usada para un bloque de código. (Para las líneas de código real, use <code>).

Sintaxis:

<c>text to be set like code</c>

Ejemplo:

''' <remarks>
''' Class <c>Point</c> models a point in a two-dimensional plane.
''' </remarks>
Public Class Point 
End Class

<código>

Esta etiqueta especifica que una o varias líneas de código fuente o salida del programa deben usar una fuente de ancho fijo. (Para fragmentos de código pequeños, use <c>).

Sintaxis:

<code>source code or program output</code>

Ejemplo:

''' <summary>
''' This method changes the point's location by the given x- and 
''' y-offsets.
''' <example>
''' For example:
''' <code>
'''    Dim p As Point = New Point(3,5)
'''    p.Translate(-1,3)
''' </code>
''' results in <c>p</c>'s having the value (2,8).
''' </example>
''' </summary>
Public Sub Translate(x As Integer, y As Integer)
    Me.x += x
    Me.y += y
End Sub

<ejemplo>

Esta etiqueta permite el código de ejemplo dentro de un comentario para mostrar cómo se puede usar un elemento. Normalmente, esto implicará el uso de la etiqueta <code> también.

Sintaxis:

<example>description</example>

Ejemplo:

Vea <code> para obtener un ejemplo.

<excepción>

Esta etiqueta proporciona una forma de documentar las excepciones que un método puede lanzar.

Sintaxis:

<exception cref="member">description</exception>

Ejemplo:

Public Module DataBaseOperations
    ''' <exception cref="MasterFileFormatCorruptException"></exception>
    ''' <exception cref="MasterFileLockedOpenException"></exception>
    Public Sub ReadRecord(flag As Integer)
        If Flag = 1 Then
            Throw New MasterFileFormatCorruptException()
        ElseIf Flag = 2 Then
            Throw New MasterFileLockedOpenException()
        End If
        ' ...
    End Sub
End Module

<incluir>

Esta etiqueta se usa para incluir información de un documento XML bien formado externo. Se aplica una expresión XPath al documento XML para especificar qué XML debe incluirse en el documento. La etiqueta <include> se reemplaza por el XML seleccionado del documento externo.

Sintaxis:

<include file="filename" path="xpath">

Ejemplo:

Si el código fuente contenía una declaración similar a la siguiente:

''' <include file="docs.xml" path="extra/class[@name="IntList"]/*" />

y el archivo externo docs.xml tenían el siguiente contenido

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

entonces, se genera la misma documentación como si el código fuente contuviera directamente esa documentación:

''' <summary>
''' Contains a list of integers.
''' </summary>

<lista>

Esta etiqueta se usa para crear una lista o una tabla de elementos. Puede contener un <listheader> bloque para definir la fila de encabezado de una tabla o lista de definiciones. (Al definir una tabla, solo se debe proporcionar una entrada para el término en el encabezado).

Cada elemento de la lista se especifica con un bloque <item>. Al crear una lista de definiciones, debe especificarse tanto el término como la descripción. Sin embargo, para una tabla, una lista con viñetas o una lista numerada, solo es necesario especificar la descripción.

Sintaxis:

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

Ejemplo:

Public Class TestClass
    ''' <remarks>
    ''' Here is an example of a bulleted list:
    ''' <list type="bullet">
    '''     <item>
    '''        <description>Item 1.</description>
    '''     </item>
    '''     <item>
    '''         <description>Item 2.</description>
    '''     </item>
    ''' </list>
    ''' </remarks>
    Public Shared Sub Main()
    End Sub
End Class

<para>

Esta etiqueta se usa dentro de otras etiquetas, como <remarks> o <returns>, y permite agregar la estructura al texto.

Sintaxis:

<para>content</para>

Ejemplo:

''' <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-trvial maintenance has
''' been performed on the Point class.</para>
''' </summary>
Public Shared Sub Main()
End Sub

<Param>

Esta etiqueta describe un parámetro para un método, constructor o propiedad indizada.

Sintaxis:

<param name="name">description</param>

Ejemplo:

''' <summary>
''' This method changes the point's location to the given
''' coordinates.
''' </summary>
''' <param name="x"><c>x</c> is the new x-coordinate.</param>
''' <param name="y"><c>y</c> is the new y-coordinate.</param>
Public Sub Move(x As Integer, y As Integer)
    Me.x = x
    Me.y = y
End Sub

<paramref>

Esta etiqueta indica que una palabra es un parámetro. El archivo de documentación se puede procesar para dar formato a este parámetro de una forma exclusiva.

Sintaxis:

<paramref name="name"/>

Ejemplo:

''' <summary>
''' This constructor initializes the new Point to
''' (<paramref name="x"/>,<paramref name="y"/>).
''' </summary>
''' <param name="x"><c>x</c> is the new Point's x-coordinate.</param>
''' <param name="y"><c>y</c> is the new Point's y-coordinate.</param>
Public Sub New(x As Integer, y As Integer)
    Me.x = x
    Me.y = y
End Sub

<permiso>

Esta etiqueta documenta la accesibilidad de seguridad de un miembro.

Sintaxis:

<permission cref="member">description</permission>

Ejemplo:

''' <permission cref="System.Security.PermissionSet">Everyone can
''' access this method.</permission>
Public Shared Sub Test()
End Sub

<observaciones>

Esta etiqueta especifica información general sobre un tipo. (Use <summary> para describir los miembros de un tipo).

Sintaxis:

<remarks>description</remarks>

Ejemplo:

''' <remarks>
''' Class <c>Point</c> models a point in a two-dimensional plane.
''' </remarks>
Public Class Point 
End Class

<Devuelve>

Esta etiqueta describe el valor devuelto de un método.

Sintaxis:

<returns>description</returns>

Ejemplo:

''' <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 Overrides Function ToString() As String
    Return "(" & x & "," & y & ")"
End Sub

<consulte>

Esta etiqueta permite especificar un vínculo dentro del texto. (Use <seealso> para indicar el texto que se va a aparecer en una sección Ver también).

Sintaxis:

<see cref="member"/>

Ejemplo:

''' <summary>
''' This method changes the point's location to the given
''' coordinates.
''' </summary>
''' <see cref="Translate"/>
Public Sub Move(x As Integer, y As Integer)
    Me.x = x
    Me.y = y
End Sub

''' <summary>
''' This method changes the point's location by the given x- and
''' y-offsets.
''' </summary>
''' <see cref="Move"/>
Public Sub Translate(x As Integer, y As Integer)
    Me.x += x
    Me.y += y
End Sub

<véase también>

Esta etiqueta genera una entrada para la sección Ver también. (Use <see> para especificar un vínculo desde el texto).

Sintaxis:

<seealso cref="member"/>

Ejemplo:

''' <summary>
''' This method determines whether two Points have the same location.
''' </summary>
''' <seealso cref="operator=="/>
''' <seealso cref="operator!="/>
Public Overrides Function Equals(o As Object) As Boolean
    ' ...
End Function

<resumen>

Esta etiqueta describe un miembro de tipo. (Use <remarks> para describir un tipo en sí).

Sintaxis:

<summary>description</summary>

Ejemplo:

''' <summary>
''' This constructor initializes the new Point to (0,0).
''' </summary>
Public Sub New()
    Me.New(0,0)
End Sub

<typeparam>

Esta etiqueta describe un parámetro de tipo.

Sintaxis:

<typeparam name="name">description</typeparam>

Ejemplo:

''' <typeparam name="T">
''' The base item type. Must implement IComparable.
''' </typeparam>
Public Class ItemManager(Of T As IComparable)
End Class

<valor>

Esta etiqueta describe una propiedad.

Sintaxis:

<value>property description</value>

Ejemplo:

''' <value>
''' Property <c>X</c> represents the point's x-coordinate.
''' </value>
Public Property X() As Integer
    Get
        Return _x
    End Get
    Set (Value As Integer)
        _x = Value
    End Set
End Property

Cadenas de identificador

Al generar el archivo de documentación, el compilador genera una cadena de identificador para cada elemento del código fuente que se etiqueta con un comentario de documentación que lo identifica de forma única. Las herramientas externas pueden usar esta cadena de identificador para identificar qué elemento de un ensamblado compilado corresponde al comentario del documento.

Las cadenas de identificador se generan de la siguiente manera:

No se coloca espacio en blanco en la cadena.

La primera parte de la cadena identifica el tipo de miembro documentado, mediante un carácter único seguido de dos puntos. Se definen los siguientes tipos de miembros, con el carácter correspondiente entre paréntesis después de él: eventos (E), campos (F), métodos que incluyen constructores y operadores (M), espacios de nombres (N), propiedades (P) y tipos (T). Un signo de exclamación (!) indica un error al generar la cadena de identificador y el resto de la cadena proporciona información sobre el error.

La segunda parte de la cadena es el nombre completo del elemento, empezando por el espacio de nombres global. El nombre del elemento, sus tipos envolventes y el espacio de nombres están separados por puntos. Si el nombre del elemento tiene puntos, se reemplazan por el signo de libra (#). (Se supone que ningún elemento tiene este carácter en su nombre). El nombre de un tipo con parámetros de tipo termina con una comillas inversas (') seguida de un número que representa el número de parámetros de tipo en el tipo. Es importante recordar que, dado que los tipos anidados tienen acceso a los parámetros de tipo de los tipos que los contienen, los tipos anidados contienen implícitamente los parámetros de tipo de sus tipos que contienen y esos tipos se cuentan en sus totales de parámetros de tipo en este caso.

En los métodos y propiedades con argumentos, la lista de argumentos aparece entre paréntesis. Si no tienen argumentos, se omiten los paréntesis. Los argumentos están separados por comas. La codificación de cada argumento es la misma que una firma de la CLI, como se indica a continuación: Los argumentos se representan mediante su nombre completo. Por ejemplo, Integer se convierte en System.Int32, String se convierte System.Stringen , Object se convierte System.Objecten y así sucesivamente. Los argumentos que tienen el ByRef modificador tienen un '@' siguiendo su nombre de tipo. Los argumentos que tienen el ByValmodificador , Optional o ParamArray no tienen notación especial. Los argumentos que son matrices se representan como [lowerbound:size, ..., lowerbound:size] donde el número de comas es el rango - 1, y los límites y el tamaño inferiores de cada dimensión, si se conocen, se representan en decimal. Si no se especifican un límite inferior ni un tamaño, se omiten. Si se omite el límite inferior y el tamaño de una dimensión determinada, también se omite ":". Las matrices de matrices se representan mediante una "[]" por nivel.

Ejemplos de cadenas de identificador

En los ejemplos siguientes se muestra un fragmento de código VB, junto con la cadena de identificador generada a partir de cada elemento de origen capaz de tener un comentario de documentación:

Los tipos se representan con su nombre completo.

Enum Color
    Red
    Blue
    Green
End Enum

Namespace Acme
    Interface IProcess
    End Interface

    Structure ValueType
        ...
    End Structure

    Class Widget
        Public Class NestedClass
        End Class

        Public Interface IMenuItem
        End Interface

        Public Delegate Sub Del(i As Integer)

        Public Enum Direction
            North
            South
            East
            West
        End Enum
    End Class
End Namespace

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

Los campos se representan mediante su nombre completo.

Namespace Acme
    Structure ValueType
        Private total As Integer
    End Structure

    Class Widget
        Public Class NestedClass
            Private value As Integer
        End Class

        Private message As String
        Private Shared defaultColor As Color
        Private Const PI As Double = 3.14159
        Protected ReadOnly monthlyAverage As Double
        Private array1() As Long
        Private array2(,) As Widget
    End Class
End Namespace

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

Constructores.

Namespace Acme
    Class Widget
        Shared Sub New()
        End Sub

        Public Sub New()
        End Sub

        Public Sub New(s As String)
        End Sub
    End Class
End Namespace

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

Métodos.

Namespace Acme
    Structure ValueType
        Public Sub M(i As Integer)
        End Sub
    End Structure

    Class Widget
        Public Class NestedClass
            Public Sub M(i As Integer)
            End Sub
        End Class

        Public Shared Sub M0()
        End Sub

        Public Sub M1(c As Char, ByRef f As Float, _
            ByRef v As ValueType)
        End Sub

        Public Sub M2(x1() As Short, x2(,) As Integer, _
            x3()() As Long)
        End Sub

        Public Sub M3(x3()() As Long, x4()(,,) As Widget)
        End Sub

        Public Sub M4(Optional i As Integer = 1)

        Public Sub M5(ParamArray args() As Object)
        End Sub
    End Class
End Namespace

"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@)"
"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.Int32)"
"M:Acme.Widget.M5(System.Object[])"

Propiedades.

Namespace Acme
    Class Widget
        Public Property Width() As Integer
            Get
            End Get
            Set (Value As Integer)
            End Set
        End Property

        Public Default Property Item(i As Integer) As Integer
            Get
            End Get
            Set (Value As Integer)
            End Set
        End Property

        Public Default Property Item(s As String, _
            i As Integer) As Integer
            Get
            End Get
            Set (Value As Integer)
            End Set
        End Property
    End Class
End Namespace

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

Eventos

Namespace Acme
    Class Widget
        Public Event AnEvent As EventHandler
        Public Event AnotherEvent()
    End Class
End Namespace

"E:Acme.Widget.AnEvent"
"E:Acme.Widget.AnotherEvent"

Operadores.

Namespace Acme
    Class Widget
        Public Shared Operator +(x As Widget) As Widget
        End Operator

        Public Shared Operator +(x1 As Widget, x2 As Widget) As Widget
        End Operator
    End Class
End Namespace

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

Los operadores de conversión tienen un final ~ seguido del tipo de valor devuelto.

Namespace Acme
    Class Widget
        Public Shared Narrowing Operator CType(x As Widget) As _
            Integer
        End Operator

        Public Shared Widening Operator CType(x As Widget) As Long
        End Operator
    End Class
End Namespace

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

Ejemplo de comentarios de documentación

En el ejemplo siguiente se muestra el código fuente de una Point clase :

Namespace Graphics
    ''' <remarks>
    ''' Class <c>Point</c> models a point in a two-dimensional
    ''' plane.
    ''' </remarks>
    Public Class Point
        ''' <summary>
        ''' Instance variable <c>x</c> represents the point's x-coordinate.
        ''' </summary>
        Private _x As Integer

        ''' <summary>
        ''' Instance variable <c>y</c> represents the point's y-coordinate.
        ''' </summary>
        Private _y As Integer

        ''' <value>
        ''' Property <c>X</c> represents the point's x-coordinate.
        ''' </value>
        Public Property X() As Integer
            Get
                Return _x
            End Get
            Set(Value As Integer)
                _x = Value
            End Set
        End Property

        ''' <value>
        ''' Property <c>Y</c> represents the point's y-coordinate.
        ''' </value>
        Public Property Y() As Integer
            Get
                Return _y
            End Get
            Set(Value As Integer)
                _y = Value
            End Set
        End Property

        ''' <summary>
        ''' This constructor initializes the new Point to (0,0).
        ''' </summary>
        Public Sub New()
            Me.New(0, 0)
        End Sub

        ''' <summary>
        ''' This constructor initializes the new Point to
        ''' (<paramref name="x"/>,<paramref name="y"/>).
        ''' </summary>
        ''' <param name="x"><c>x</c> is the new Point's
        ''' x-coordinate.</param>
        ''' <param name="y"><c>y</c> is the new Point's
        ''' y-coordinate.</param>
        Public Sub New(x As Integer, y As Integer)
            Me.X = x
            Me.Y = y
        End Sub

        ''' <summary>
        ''' This method changes the point's location to the given
        ''' coordinates.
        ''' </summary>
        ''' <param name="x"><c>x</c> is the new x-coordinate.</param>
        ''' <param name="y"><c>y</c> is the new y-coordinate.</param>
        ''' <see cref="Translate"/>
        Public Sub Move(x As Integer, y As Integer)
            Me.X = x
            Me.Y = y
        End Sub

        ''' <summary>
        ''' This method changes the point's location by the given x- and
        ''' y-offsets.
        ''' <example>
        ''' For example:
        ''' <code>
        '''    Dim p As Point = New Point(3, 5)
        '''    p.Translate(-1, 3)
        ''' </code>
        ''' results in <c>p</c>'s having the value (2,8).
        ''' </example>
        ''' </summary>
        ''' <param name="x"><c>x</c> is the relative x-offset.</param>
        ''' <param name="y"><c>y</c> is the relative y-offset.</param>
        ''' <see cref="Move"/>
        Public Sub Translate(x As Integer, y As Integer)
            Me.X += x
            Me.Y += y
        End Sub

        ''' <summary>
        ''' This method determines whether two Points have the same
        ''' location.
        ''' </summary>
        ''' <param name="o"><c>o</c> is 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 op_Equality"/>
        ''' <seealso cref="Operator op_Inequality"/>
        Public Overrides Function Equals(o As Object) As Boolean
            If o Is Nothing Then
                Return False
            End If
            If o Is Me Then
                Return True
            End If
            If Me.GetType() Is o.GetType() Then
                Dim p As Point = CType(o, Point)
                Return (X = p.X) AndAlso (Y = p.Y)
            End If
            Return False
        End Function

        ''' <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 Overrides Function ToString() As String
            Return "(" & X & "," & Y & ")"
        End Function

        ''' <summary>
        ''' This operator determines whether two Points have the
        ''' same location.
        ''' </summary>
        ''' <param name="p1"><c>p1</c> is the first Point to be compared.
        ''' </param>
        ''' <param name="p2"><c>p2</c> is 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="op_Inequality"/>
        Public Shared Operator =(p1 As Point, p2 As Point) As Boolean
            If p1 Is Nothing OrElse p2 Is Nothing Then
                Return False
            End If
            If p1.GetType() Is p2.GetType() Then
                Return (p1.X = p2.X) AndAlso (p1.Y = p2.Y)
            End If
            Return False
        End Operator

        ''' <summary>
        ''' This operator determines whether two Points have the
        ''' same location.
        ''' </summary>
        ''' <param name="p1"><c>p1</c> is the first Point to be comapred.
        ''' </param>
        ''' <param name="p2"><c>p2</c> is 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="op_Equality"/>
        Public Shared Operator <>(p1 As Point, p2 As Point) As Boolean
            Return Not p1 = p2
        End Operator

        ''' <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-trvial maintenance has
        ''' been performed on the Point class.</para>
        ''' </summary>
        Public Shared Sub Main()
            ' class test code goes here
        End Sub
    End Class
End Namespace

Esta es la salida generada cuando se proporciona el código fuente de la clase Point, que se muestra anteriormente:

<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Point</name>
    </assembly>
    <members>
        <member name="T:Graphics.Point">
            <remarks>Class <c>Point</c> models a point in a
            two-dimensional plane. </remarks>
        </member>
        <member name="F:Graphics.Point.x">
            <summary>Instance variable <c>x</c> represents the point's
            x-coordinate.</summary>
        </member>
        <member name="F:Graphics.Point.y">
            <summary>Instance variable <c>y</c> represents the point's
            y-coordinate.</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="x"/>,<paramref name="y"/>).</summary>
            <param><c>x</c> is the new Point's x-coordinate.</param>
            <param><c>y</c> is 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.</summary>
            <param><c>x</c> is the new x-coordinate.</param>
            <param><c>y</c> is the new y-coordinate.</param>
            <see cref=
            "M:Graphics.Point.Translate(System.Int32,System.Int32)"/>
        </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>
            </summary>
            <param><c>x</c> is the relative x-offset.</param>
            <param><c>y</c> is the relative y-offset.</param>
            <see cref="M:Graphics.Point.Move(System.Int32,System.Int32)"/>
        </member>
        <member name="M:Graphics.Point.Equals(System.Object)">
            <summary>This method determines whether two Points have the
            same location.</summary>
            <param><c>o</c> is 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><c>p1</c> is the first Point to be compared.</param>
            <param><c>p2</c> is 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><c>p1</c> is the first Point to be compared.</param>
            <param><c>p2</c> is 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-trvial 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>