Commenti alla documentazione allegato D
Questo allegato è informativo.
D.1 Generale
C# fornisce un meccanismo per i programmatori per documentare il codice usando una sintassi di commento che contiene testo XML. Nei file di codice sorgente, i commenti con un determinato modulo possono essere usati per indirizzare uno strumento per produrre codice XML da tali commenti e dagli elementi del codice sorgente, che precedono. I commenti che usano tale sintassi sono detti commenti della documentazione. Devono precedere immediatamente un tipo definito dall'utente (ad esempio una classe, un delegato o un'interfaccia) o un membro (ad esempio un campo, un evento, una proprietà o un metodo). Lo strumento di generazione XML è denominato generatore di documentazione. Questo generatore potrebbe essere, ma non è necessario, il compilatore C#stesso. L'output prodotto dal generatore di documentazione è denominato file di documentazione. Un file di documentazione viene usato come input per un visualizzatore di documentazione; uno strumento destinato a produrre una sorta di visualizzazione visiva delle informazioni sul tipo e della relativa documentazione associata.
Non è necessario un compilatore C# conforme per controllare la sintassi dei commenti della documentazione; tali commenti sono semplicemente commenti ordinari. Un compilatore conforme è tuttavia autorizzato a eseguire tale controllo.
Questa specifica suggerisce un set di tag standard da usare nei commenti della documentazione, ma l'uso di questi tag non è obbligatorio e altri tag possono essere usati se necessario, purché vengano seguite le regole di XML ben formato. Per le implementazioni C# destinate all'interfaccia della riga di comando, fornisce anche informazioni sul generatore di documentazione e sul formato del file di documentazione. Non vengono fornite informazioni sul visualizzatore della documentazione.
D.2 Introduzione
I commenti con un determinato modulo possono essere utilizzati per indirizzare uno strumento per produrre codice XML da tali commenti e dagli elementi del codice sorgente che precedono. Tali commenti sono Single_Line_Comment (§6.3.3) che iniziano con tre barre (///
) o Delimited_Comments (§6.3.3) che iniziano con una barra e due asterischi (/**
). Devono precedere immediatamente un tipo definito dall'utente o un membro che annotano. Le sezioni degli attributi (§22.3) sono considerate parte delle dichiarazioni, pertanto i commenti della documentazione devono precedere gli attributi applicati a un tipo o a un membro.
Ai fini dell'esposizione, il formato dei commenti del documento è illustrato di seguito come due regole grammaticali: Single_Line_Doc_Comment e Delimited_Doc_Comment. Tuttavia, queste regole non fanno parte della grammatica C#, ma rappresentano invece formati specifici di Single_Line_Comment e Delimited_Comment regole lexer, rispettivamente.
Sintassi:
Single_Line_Doc_Comment
: '///' Input_Character*
;
Delimited_Doc_Comment
: '/**' Delimited_Comment_Section* ASTERISK+ '/'
;
In un Single_Line_Doc_Comment, se è presente un carattere spazio vuoto che segue i ///
caratteri in ogni Single_Line_Doc_Comments adiacente al Single_Line_Doc_Comment corrente, tale carattere di spazio vuoto non è incluso nell'output XML.
In un Delimited_Doc_Comment, se il primo carattere non spazio vuoto nella seconda riga è un ASTERISK e lo stesso modello di spazi vuoti facoltativi e un carattere ASTERISK viene ripetuto all'inizio di ognuna delle righe all'interno del Delimited_Doc_Comment, i caratteri del criterio ripetuto non vengono inclusi nell'output XML. Il criterio può includere caratteri di spazio vuoto dopo, nonché prima, il carattere ASTERISK .
Esempio:
/// <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() {...}
}
Il testo all'interno dei commenti della documentazione deve essere ben formato in base alle regole di XML (http://www.w3.org/TR/REC-xml). Se il formato XML non è valido, viene generato un avviso e il file della documentazione conterrà un commento che indica che è stato rilevato un errore.
Anche se gli sviluppatori sono liberi di creare un proprio set di tag, un set consigliato è definito in §D.3. Alcuni tag consigliati hanno un significato speciale:
Il tag
<param>
viene usato per descrivere i parametri. Se viene usato un tag di questo tipo, il generatore di documentazione deve verificare che il parametro specificato esista e che tutti i parametri siano descritti nei commenti della documentazione. Se la verifica ha esito negativo, il generatore di documentazione genera un avviso.L'attributo
cref
può essere associato a qualsiasi tag per fornire un riferimento a un elemento del codice. Il generatore di documentazione deve verificare che questo elemento di codice esista. Se la verifica non riesce, il generatore di documentazione genera un avviso. Quando si cerca un nome descritto in uncref
attributo, il generatore di documentazione deve rispettare la visibilità dello spazio dei nomi in base alle istruzioni using visualizzate all'interno del codice sorgente. Per gli elementi di codice generici, non è possibile usare la normale sintassi generica ,ad esempio "List<T>
", perché produce codice XML non valido. Le parentesi graffe possono essere usate invece delle parentesi quadre (ad esempio; "List{T}
") o la sintassi di escape XML può essere usata (ad esempio, "List<T>
").Il
<summary>
tag deve essere usato da un visualizzatore di documentazione per visualizzare informazioni aggiuntive su un tipo o un membro.Il
<include>
tag include informazioni provenienti da un file XML esterno.
Si noti con attenzione che il file di documentazione non fornisce informazioni complete sul tipo e sui membri ( ad esempio, non contiene informazioni sul tipo). Per ottenere tali informazioni su un tipo o un membro, è necessario utilizzare il file di documentazione insieme alla reflection sul tipo o sul membro.
D.3 Tag consigliati
D.3.1 Generale
Il generatore di documentazione deve accettare ed elaborare qualsiasi tag valido in base alle regole di XML. I tag seguenti forniscono funzionalità di uso comune nella documentazione dell'utente. Naturalmente, sono possibili altri tag.
Tag | Riferimento | Scopo |
---|---|---|
<c> |
§D.3.2 | Impostare il testo in un tipo di carattere simile al codice |
<code> |
§D.3.3 | Impostare una o più righe di codice sorgente o output del programma |
<example> |
§D.3.4 | Indicare un esempio |
<exception> |
§D.3.5 | Identifica le eccezioni che un metodo può generare |
<include> |
§D.3.6 | Include XML da un file esterno |
<list> |
§D.3.7 | Creare un elenco o una tabella |
<para> |
§D.3.8 | Consenti l'aggiunta della struttura al testo |
<param> |
§D.3.9 | Descrivere un parametro per un metodo o un costruttore |
<paramref> |
§D.3.10 | Identificare che una parola è un nome di parametro |
<permission> |
§D.3.11 | Documentare l'accessibilità della sicurezza di un membro |
<remarks> |
§D.3.12 | Descrivere informazioni aggiuntive su un tipo |
<returns> |
§D.3.13 | Descrivere il valore restituito di un metodo |
<see> |
§D.3.14 | Specificare un collegamento |
<seealso> |
§D.3.15 | Generare una voce Vedere anche |
<summary> |
§D.3.16 | Descrivere un tipo o un membro di un tipo |
<typeparam> |
§D.3.17 | Descrivere un parametro di tipo per un tipo o un metodo generico |
<typeparamref> |
§D.3.18 | Identificare che una parola è un nome di parametro di tipo |
<value> |
§D.3.19 | Descrivere una proprietà |
D.3.2 <c>
Questo tag fornisce un meccanismo per indicare che un frammento di testo all'interno di una descrizione deve essere impostato in un tipo di carattere speciale, ad esempio quello usato per un blocco di codice. Per le righe di codice effettivo, usare <code>
(§D.3.3).
Sintassi:
<c>
Testo</c>
Esempio:
/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
public class Point
{
}
Codice D.3.3 <>
Questo tag viene usato per impostare una o più righe di codice sorgente o output del programma in un tipo di carattere speciale. Per frammenti di codice di piccole dimensioni nella narrazione, usare <c>
(§D.3.2).
Sintassi:
<code>
codice sorgente o output del programma</code>
Esempio:
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)
{
...
}
}
Esempio D.3.4 <>
Questo tag consente al codice di esempio all'interno di un commento di specificare la modalità di utilizzo di un metodo o di un altro membro della libreria. In genere, ciò implica anche l'uso del tag <code>
(§D.3.3).
Sintassi:
<example>
description</example>
Esempio:
Per un esempio, vedere <code>
(§D.3.3).
Eccezione D.3.5 <>
Questo tag consente di documentare le eccezioni che un metodo può generare.
Sintassi:
<exception cref="
Descrizione membro">
</exception>
where
cref="
member"
è il nome di un membro. Il generatore di documentazione verifica che il membro specificato esista e converta il membro nel nome dell'elemento canonico nel file di documentazione.- description è una descrizione delle circostanze in cui viene generata l'eccezione.
Esempio:
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 <include>
Questo tag consente di includere informazioni da un documento XML esterno al file di codice sorgente. Il file esterno deve essere un documento XML ben formato e a tale documento viene applicata un'espressione XPath per specificare il codice XML da tale documento da includere. Il <include>
tag viene quindi sostituito con il codice XML selezionato dal documento esterno.
Sintassi:
<include file="
filename" path="
xpath" />
where
file="
filename"
è il nome file di un file XML esterno. Il nome file viene interpretato in relazione al file che contiene il tag di inclusione.path="
xpath"
è un'espressione XPath che seleziona parte del codice XML nel file XML esterno.
Esempio:
Se il codice sorgente contiene una dichiarazione simile alla seguente:
/// <include file="docs.xml" path='extradoc/class[@name="IntList"]/*' />
public class IntList { ... }
e il file esterno "docs.xml" aveva il contenuto seguente:
<?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>
la stessa documentazione viene restituita come se il codice sorgente fosse contenuto:
/// <summary>
/// Contains a list of integers.
/// </summary>
public class IntList { ... }
Elenco D.3.7 <>
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>
where
- il termine è il termine da definire, la cui definizione è in descrizione.
- description è un elemento in un elenco puntato o numerato o la definizione di un termine.
Esempio:
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>
Questo tag è destinato all'uso all'interno di altri tag, ad esempio <summary>
(§D.3.16) o <returns>
(§D.3.13) e consente l'aggiunta della struttura al testo.
Sintassi:
<para>
content</para>
where
- content è il testo del paragrafo.
Esempio:
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()
{
...
}
}
D.3.9 <param>
Questo tag viene usato per descrivere un parametro per un metodo, un costruttore o un indicizzatore.
Sintassi:
<param name="
nome">
descrizione</param>
where
- name è il nome del parametro.
- description è una descrizione del parametro.
Esempio:
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>
Questo tag viene usato per indicare che una parola è un parametro. Il file di documentazione può essere elaborato per formattare questo parametro in modo distinto.
Sintassi:
<paramref name="
name"/>
where
- name è il nome del parametro.
Esempio:
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)
{
...
}
}
Autorizzazione D.3.11 <>
Questo tag consente di documentare l'accessibilità della sicurezza di un membro.
Sintassi:
<permission cref="
Descrizione membro">
</permission>
where
- member è il nome di un membro. Il generatore di documentazione verifica che l'elemento di codice specificato esista e converta il membro nel nome dell'elemento canonico nel file di documentazione.
- description è una descrizione dell'accesso al membro.
Esempio:
public class MyClass
{
/// <permission cref="System.Security.PermissionSet">
/// Everyone can access this method.
/// </permission>
public static void Test()
{
...
}
}
D.3.12 <osservazioni>
Questo tag viene usato per specificare informazioni aggiuntive su un tipo. Utilizzare <summary>
(§D.3.16) per descrivere il tipo stesso e i membri di un tipo.
Sintassi:
<remarks>
description</remarks>
where
- description è il testo della nota.
Esempio:
/// <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 <restituisce>
Questo tag viene usato per descrivere il valore restituito di un metodo.
Sintassi:
<returns>
description</returns>
where
- description è una descrizione del valore restituito.
Esempio:
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 <vedere>
Questo tag consente di specificare un collegamento all'interno del testo. Utilizzare <seealso>
(§D.3.15) per indicare il testo da visualizzare in una sottoclausa Vedere anche .
Sintassi:
<see cref="
Parola chiave urlmembro" href="
" langword="
" />
where
- member è il nome di un membro. Il generatore di documentazione verifica che l'elemento di codice specificato esista e modifiche al nome dell'elemento nel file di documentazione generato.
- URL è un riferimento a un'origine esterna.
- langword è una parola da evidenziare in qualche modo.
Esempio:
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 <seealso>
Questo tag consente di generare una voce per la sottochiave See Also . Utilizzare <see>
(§D.3.14) per specificare un collegamento dal testo.
Sintassi:
<seealso cref="
URL membro" href="
" />
where
- member è il nome di un membro. Il generatore di documentazione verifica che l'elemento di codice specificato esista e modifiche al nome dell'elemento nel file di documentazione generato.
- URL è un riferimento a un'origine esterna.
Esempio:
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)
{
...
}
}
Riepilogo D.3.16 <>
Questo tag può essere usato per descrivere un tipo o un membro di un tipo. Utilizzare <remarks>
(§D.3.12) per specificare informazioni aggiuntive sul tipo o sul membro.
Sintassi:
<summary>
description</summary>
where
- description è un riepilogo del tipo o del membro.
Esempio:
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>
Questo tag viene usato per descrivere un parametro di tipo per un tipo o un metodo generico.
Sintassi:
<typeparam name="
nome">
descrizione</typeparam>
where
- name è il nome del parametro di tipo.
- description è una descrizione del parametro di tipo.
Esempio:
/// <summary>A generic list class.</summary>
/// <typeparam name="T">The type stored by the list.</typeparam>
public class MyList<T>
{
...
}
D.3.18 <typeparamref>
Questo tag viene usato per indicare che una parola è un parametro di tipo. Il file di documentazione può essere elaborato per formattare questo parametro di tipo in modo distinto.
Sintassi:
<typeparamref name="
name"/>
where
- name è il nome del parametro di tipo.
Esempio:
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)
{
...
}
}
Valore D.3.19 <>
Questo tag consente di descrivere una proprietà.
Sintassi:
<value>
descrizione proprietà</value>
where
- la descrizione della proprietà è una descrizione per la proprietà .
Esempio:
public class Point
{
/// <value>Property <c>X</c> represents the point's x-coordinate.</value>
public int X { get; set; }
}
D.4 Elaborazione del file di documentazione
D.4.1 Generale
Le informazioni seguenti sono destinate alle implementazioni C# destinate all'interfaccia della riga di comando.
Il generatore di documentazione genera una stringa ID per ogni elemento nel codice sorgente contrassegnato con un commento della documentazione. Questa stringa ID identifica in modo univoco un elemento di origine. Un visualizzatore di documentazione può usare una stringa ID per identificare l'elemento corrispondente a cui si applica la documentazione.
Il file di documentazione non è una rappresentazione gerarchica del codice sorgente; è piuttosto un elenco semplice con una stringa ID generata per ogni elemento.
Formato stringa ID D.4.2
Il generatore di documentazione osserva le regole seguenti quando genera le stringhe ID:
Assenza di spazi vuoti nella stringa.
La prima parte della stringa identifica il tipo di membro documentato, tramite un singolo carattere seguito da due punti. Vengono definiti i tipi di membri seguenti:
Carattere Descrizione E Event F Campo M Metodo (inclusi costruttori, finalizzatori e operatori) N Spazio dei nomi P Proprietà (inclusi gli indicizzatori) T Tipo (ad esempio classe, delegato, enumerazione, interfaccia e struct) ! Stringa di errore; il resto della stringa fornisce informazioni sull'errore. Ad esempio, il generatore di documentazione genera informazioni sull'errore per i collegamenti che non possono essere risolti. La seconda parte della stringa è il nome completo dell'elemento, a partire dalla radice dello spazio dei nomi. 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 da caratteri # (U+0023). Si presuppone che nessun elemento abbia questo carattere nel nome. Gli argomenti di tipo nel nome completo, per quando un membro implementa in modo esplicito un membro di un'interfaccia generica, vengono codificati sostituendo "
<
" e ">
" che li circondano con i caratteri "{
" e "}
".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 della documentazione, che si basa sul nome completo, modificato nel modo seguente:
- Gli argomenti che rappresentano tipi generici hanno un carattere "
'
" aggiunto seguito dal numero di parametri di tipo - Gli argomenti con il
in
modificatore oout
ref
hanno un@
nome di tipo seguente. Gli argomenti passati per valore o tramiteparams
non hanno una notazione speciale. - Gli argomenti che sono matrici sono rappresentati come
[
dimensioni,
in ingresso:
inferiore ...,
lowerbound:
grandezza]
dove il numero di virgole è il rango minore di uno 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 frastagliate sono rappresentate da un "[]
" per livello. Le matrici unidimensionali omettono il limite inferiore quando il limite inferiore è 0 (impostazione predefinita) (§17.1). - Gli argomenti con tipi di puntatore diversi da
void
sono rappresentati usando un*
nome di tipo seguente. Unvoid
puntatore viene rappresentato usando un nome di tipo .System.Void
- Gli argomenti che fanno riferimento ai parametri di tipo generici definiti nei tipi vengono codificati usando il carattere "
`
" seguito dall'indice in base zero del parametro di tipo. - Gli argomenti che usano parametri di tipo generico definiti nei metodi usano un doppio backtick "
``
" anziché "`
" usato per i tipi. - Gli argomenti che fanno riferimento ai tipi generici costruiti vengono codificati usando il tipo generico, seguito da "
{
", seguito da un elenco delimitato da virgole di argomenti di tipo, seguito da "}
".
- Gli argomenti che rappresentano tipi generici hanno un carattere "
- Gli argomenti sono rappresentati dal nome della documentazione, che si basa sul nome completo, modificato nel modo seguente:
Esempi di stringhe ID D.4.3
Gli esempi seguenti mostrano ogni frammento di codice C#, 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, incrementati con informazioni generiche:
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> { ... }
}
}
Id:
"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"
I campi sono rappresentati dal nome completo.
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;
}
}
Id:
"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"
Costruttori
namespace Acme
{
class Widget : IProcess
{
static Widget() { ... }
public Widget() { ... }
public Widget(string s) { ... }
}
}
Id:
"M:Acme.Widget.#cctor"
"M:Acme.Widget.#ctor"
"M:Acme.Widget.#ctor(System.String)"
Finalizzatori
namespace Acme
{
class Widget : IProcess
{
~Widget() { ... }
}
}
Id:
"M:Acme.Widget.Finalize"
Metodi
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) { ... }
}
}
Id:
"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)"
Proprietà e indicizzatori
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 { ... } }
}
}
Id:
"P:Acme.Widget.Width"
"P:Acme.Widget.Item(System.Int32)"
"P:Acme.Widget.Item(System.String,System.Int32)"
Eventi
namespace Acme
{
class Widget : IProcess
{
public event Del AnEvent;
}
}
Id:
"E:Acme.Widget.AnEvent"
Operatori unari
namespace Acme
{
class Widget : IProcess
{
public static Widget operator+(Widget x) { ... }
}
}
Id:
"M:Acme.Widget.op_UnaryPlus(Acme.Widget)"
Il set completo di nomi di funzione dell'operatore unario usati è il seguente: op_UnaryPlus
, , op_Decrement
op_OnesComplement
op_LogicalNot
op_Increment
op_UnaryNegation
, , op_True
e .op_False
Operatori binari
namespace Acme
{
class Widget : IProcess
{
public static Widget operator+(Widget x1, Widget x2) { ... }
}
}
Id:
"M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)"
Il set completo di nomi di funzione dell'operatore binario usati è il seguente: , , op_Division
, , , op_RightShift
op_LessThanOrEqual
op_LeftShift
op_LessThan
op_GreaterThan
op_Inequality
op_Equality
op_ExclusiveOr
op_BitwiseAnd
op_BitwiseOr
e .op_GreaterThanOrEqual
op_Modulus
op_Multiply
op_Subtraction
op_Addition
Gli operatori di conversione hanno un "~
" finale seguito dal tipo restituito. Quando l'origine o la destinazione di un operatore di conversione è un tipo generico, i caratteri "<
" e "">
" vengono sostituiti rispettivamente dai caratteri "{
" e "}
".
namespace Acme
{
class Widget : IProcess
{
public static explicit operator int(Widget x) { ... }
public static implicit operator long(Widget x) { ... }
}
}
Id:
"M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32"
"M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64"
D.5 Esempio
Codice sorgente C# D.5.1
L'esempio seguente illustra il codice sorgente di una 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 risultante
Di seguito è riportato l'output prodotto da un generatore di documentazione quando viene fornito il codice sorgente per la classe Point
, illustrato sopra:
<?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>
Fine del testo informativo.
ECMA C# draft specification