Commenti sulla documentazione

I commenti della documentazione sono commenti in formato speciale nell'origine che possono essere analizzati per produrre documentazione sul codice a cui sono collegati. Il formato di base per i commenti della documentazione è XML. Quando il codice di compilazione con commenti della documentazione, il compilatore può facoltativamente generare un file XML che rappresenta la somma totale dei commenti della documentazione nell'origine. Questo file XML può quindi essere usato da altri strumenti per produrre documentazione stampata o online.

Questo capitolo descrive i commenti del documento e i tag XML consigliati da utilizzare con i commenti del documento.

Formato commento documentazione

I commenti del documento sono commenti speciali che iniziano con ''', tre virgolette singole. Devono precedere immediatamente il tipo (ad esempio una classe, un delegato o un'interfaccia) o un membro di tipo (ad esempio un campo, un evento, una proprietà o un metodo) che documentano. Un commento del documento su una dichiarazione di metodo parziale verrà sostituito dal commento del documento sul metodo che ne fornisce il corpo, se presente. Tutti i commenti del documento adiacenti vengono aggiunti insieme per produrre un singolo commento del documento. Se è presente un carattere di spazio vuoto che segue i ''' caratteri, tale carattere di spazio vuoto non viene incluso nella concatenazione. Per esempio:

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

I commenti della documentazione devono essere xml ben formati in base a https://www.w3.org/TR/REC-xml. Se il formato XML non è corretto, viene generato un avviso e il file della documentazione conterrà un commento che indica che è stato rilevato un errore.

Sebbene gli sviluppatori siano liberi di creare un proprio set di tag, nella sezione successiva viene definito un set consigliato. Alcuni tag consigliati hanno un significato speciale:

  • Il tag <param> viene usato per descrivere i parametri. Il parametro specificato da un <param> tag deve esistere e tutti i parametri del membro di tipo devono essere descritti nel commento della documentazione. Se una delle due condizioni non è true, il compilatore genera un avviso.

  • L'attributo cref può essere associato a qualsiasi tag per fornire un riferimento a un elemento del codice. L'elemento di codice deve esistere; in fase di compilazione il compilatore sostituisce il nome con la stringa ID che rappresenta il membro. Se l'elemento di codice non esiste, il compilatore genera un avviso. Quando si cerca un nome descritto in un cref attributo, il compilatore rispetta le Imports istruzioni visualizzate all'interno del file di origine contenitore.

  • Il <summary> tag deve essere usato da un visualizzatore di documentazione per visualizzare informazioni aggiuntive su un tipo o un membro.

Si noti che il file della documentazione non fornisce informazioni complete su un tipo e sui membri, ma solo ciò che è contenuto nei commenti del documento. Per ottenere altre informazioni su un tipo o un membro, è necessario usare il file di documentazione insieme alla reflection sul tipo o sul membro effettivo.

Il generatore di documentazione deve accettare ed elaborare qualsiasi tag valido in base alle regole di XML. I tag seguenti forniscono funzionalità comunemente usate nella documentazione dell'utente:

<c> Imposta il testo in un tipo di carattere simile al codice

<code> Imposta una o più righe di codice sorgente o output del programma in un tipo di carattere simile al codice

<example> Indica un esempio

<exception> Identifica le eccezioni che un metodo può generare

<include> Include un documento XML esterno

<list> Crea un elenco o una tabella

<para> Consente l'aggiunta della struttura al testo

<param> Descrive un parametro per un metodo o un costruttore

<paramref> Identifica che una parola è un nome di parametro

<permission> Documenta l'accessibilità della sicurezza di un membro

<remarks> Descrive un tipo

<returns> Descrive il valore restituito di un metodo

<see> Specifica un collegamento

<seealso> Genera una voce Vedere anche

<summary> Descrive un membro di un tipo

<typeparam> Descrive un parametro di tipo

<value> Descrive una proprietà

<c>

Questo tag specifica che un frammento di testo all'interno di una descrizione deve utilizzare un tipo di carattere simile a quello usato per un blocco di codice. Per le righe di codice effettivo, usare <code>.)

Sintassi:

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

Esempio:

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

<codice>

Questo tag specifica che una o più righe di codice sorgente o output del programma devono utilizzare un tipo di carattere a larghezza fissa. Per frammenti di codice di piccole dimensioni, usare <c>.)

Sintassi:

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

Esempio:

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

<Esempio>

Questo tag consente al codice di esempio all'interno di un commento di mostrare come usare un elemento. In genere, questo comporta anche l'uso del tag <code> .

Sintassi:

<example>description</example>

Esempio:

Per un esempio, vedere <code>.

<eccezione>

Questo tag consente di documentare le eccezioni che un metodo può generare.

Sintassi:

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

Esempio:

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

<includere>

Questo tag viene usato per includere informazioni da un documento XML ben formato esterno. Al documento XML viene applicata un'espressione XPath per specificare il codice XML da includere nel documento. Il <include> tag viene quindi sostituito con il codice XML selezionato dal documento esterno.

Sintassi:

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

Esempio:

Se il codice sorgente contiene una dichiarazione simile alla seguente:

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

e il file esterno docs.xml aveva il contenuto seguente

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

la stessa documentazione viene restituita come se il codice sorgente fosse contenuto:

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

<lista>

Questo tag viene usato per creare un elenco o una tabella di elementi. Può contenere un <listheader> blocco per definire la riga di intestazione di una tabella o di un elenco di definizioni. Quando si definisce una tabella, è necessario specificare solo una voce per il termine nell'intestazione.

Ogni elemento dell'elenco viene specificato tramite un blocco <item>. Quando si crea un elenco di definizioni, è necessario specificare sia il termine che la descrizione. Tuttavia, per una tabella, un elenco puntato o un elenco numerato, è necessario specificare solo la descrizione.

Sintassi:

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

Esempio:

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>

Questo tag è destinato all'uso all'interno di altri tag, ad esempio <remarks> o <returns>, e consente l'aggiunta della struttura al testo.

Sintassi:

<para>content</para>

Esempio:

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

Questo tag descrive un parametro per un metodo, un costruttore o una proprietà indicizzata.

Sintassi:

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

Esempio:

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

Questo tag indica che una parola è un parametro. Il file di documentazione può essere elaborato per formattare questo parametro in modo distinto.

Sintassi:

<paramref name="name"/>

Esempio:

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

<permesso>

Questo tag documenta l'accessibilità della sicurezza di un membro

Sintassi:

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

Esempio:

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

<osservazioni>

Questo tag specifica informazioni generali su un tipo. Usare <summary> per descrivere i membri di un tipo.

Sintassi:

<remarks>description</remarks>

Esempio:

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

<restituisce>

Questo tag descrive il valore restituito di un metodo.

Sintassi:

<returns>description</returns>

Esempio:

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

<vedere>

Questo tag consente di specificare un collegamento all'interno del testo. Usare <seealso> per indicare il testo da visualizzare in una sezione Vedere anche.

Sintassi:

<see cref="member"/>

Esempio:

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

<vedi anche>

Questo tag genera una voce per la sezione Vedere anche . Usare <see> per specificare un collegamento dall'interno di testo.

Sintassi:

<seealso cref="member"/>

Esempio:

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

<sommario>

Questo tag descrive un membro del tipo. Usare <remarks> per descrivere un tipo stesso.

Sintassi:

<summary>description</summary>

Esempio:

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

<typeparam>

Questo tag descrive un parametro di tipo.

Sintassi:

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

Esempio:

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

<valore>

Questo tag descrive una proprietà.

Sintassi:

<value>property description</value>

Esempio:

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

Stringhe ID

Quando si genera il file di documentazione, il compilatore genera una stringa ID per ogni elemento nel codice sorgente contrassegnato con un commento della documentazione che lo identifica in modo univoco. Questa stringa ID può essere utilizzata da strumenti esterni per identificare quale elemento in un assembly compilato corrisponde al commento del documento.

Le stringhe ID vengono generate nel modo seguente:

Nessuno spazio bianco è collocato nella stringa.

La prima parte della stringa identifica il tipo di membro documentato, tramite un singolo carattere seguito da due punti. I tipi di membri seguenti vengono definiti, con il carattere corrispondente tra parentesi dopo di esso: eventi (E), campi (F), metodi che includono costruttori e operatori (M), spazi dei nomi (N), proprietà (P) e tipi (T). Un punto esclamativo (!) indica che si è verificato un errore durante la generazione della stringa ID e il resto della stringa fornisce informazioni sull'errore.

La seconda parte della stringa è il nome completo dell'elemento, a partire dallo spazio dei nomi globale. Il nome dell'elemento, i tipi di inclusione e lo spazio dei nomi sono separati da punti. Se il nome dell'elemento stesso ha punti, vengono sostituiti dal segno di cancelletto (#). Si presuppone che nessun elemento abbia questo carattere nel nome. Il nome di un tipo con parametri di tipo termina con una virgoletta rovesciata (') seguita da un numero che rappresenta il numero di parametri di tipo nel tipo. È importante ricordare che poiché i tipi annidati hanno accesso ai parametri di tipo dei tipi che li contengono, i tipi annidati contengono in modo implicito i parametri di tipo dei tipi contenenti e tali tipi vengono conteggiati nei totali dei parametri di tipo in questo caso.

Per i metodi e le proprietà con argomenti, l'elenco di argomenti segue, racchiuso tra parentesi. Per quelli senza argomenti, le parentesi vengono omesse. Gli argomenti sono separati da virgole. La codifica di ogni argomento è uguale a una firma dell'interfaccia della riga di comando, come indicato di seguito: Gli argomenti sono rappresentati dal nome completo. Ad esempio, Integer diventa System.Int32, String diventa System.String, Object diventa System.Objecte così via. Gli argomenti con il ByRef modificatore hanno un valore '@' dopo il nome del tipo. Gli argomenti con il ByValmodificatore o OptionalParamArray non hanno una notazione speciale. Gli argomenti che sono matrici sono rappresentati come [lowerbound:size, ..., lowerbound:size] dove il numero di virgole è il rango - 1 e i limiti e le dimensioni inferiori di ogni dimensione, se noto, sono rappresentati in decimale. Se non viene specificato un limite o una dimensione inferiore, viene omesso. Se il limite inferiore e le dimensioni per una determinata dimensione vengono omessi, viene omesso anche ':'. Le matrici di matrici sono rappresentate da un "[]" per livello.

Esempi di stringhe ID

Gli esempi seguenti mostrano ogni frammento di codice VB, insieme alla stringa ID prodotta da ogni elemento di origine in grado di avere un commento della documentazione:

I tipi vengono rappresentati usando il nome 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"

I campi sono rappresentati dal nome 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"

Costruttori.

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

Metodi.

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

Proprietà.

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

Avvenimenti

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

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

Operatori.

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

Gli operatori di conversione hanno un carattere finale ~ seguito dal tipo restituito.

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"

Esempio di commenti della documentazione

L'esempio seguente mostra il codice sorgente di una Point classe:

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

Di seguito è riportato l'output generato quando viene fornito il codice sorgente per la classe Point, illustrato in precedenza:

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