Write XML documentation comments

DocInsight combines Delphi declarations with XML documentation comments to generate API reference. Place a consecutive block of /// comments immediately before the declaration it describes:

pascal
/// <summary>
///   Provides a resizable array-backed list.
/// </summary>
TArrayList<T> = class(TInterfacedObject, IList<T>)
end;

Write the documentation on the declaration in the interface section whenever possible. Describe the API contract that callers need rather than repeating information already visible in the declaration.

If you use the Delphi IDE extension, open Documentation Inspector to edit common XML documentation sections in a visual editor without writing the XML markup by hand. Use Documentation Explorer to browse declarations and review their rendered documentation. The comments remain stored with the declarations in Delphi source.

Choose documentation sections

Use a summary for the main description, then add only the sections needed by the declaration:

Element

Purpose

<summary>

Concise description of the declaration

<typeparam>

Role of a generic type parameter

<param>

Meaning and constraints of a method parameter

<returns>

Result returned by a function

<value>

Value exposed by a property

<remarks>

Behavior, ownership, side effects, or usage guidance

<exception>

Exception and the condition that raises it

<example>

Focused usage example

<seealso>

Related symbol, documentation topic, or external resource

A consistent order makes source comments easier to review: summary, type parameters, parameters, return or property value, remarks, exceptions, examples, and related links.

Document units and types

Place a unit comment before the unit declaration. Use the summary to define the unit's responsibility and remarks to identify its main entry points or important design context:

pascal
/// <summary>
///   Defines the public collection abstractions and factory methods for MyLibrary.
/// </summary>
/// <remarks>
///   The primary entry points are <see cref="IList{T}" />,
///   <see cref="IDictionary{TKey,TValue}" />, and
///   <see cref="TCollections" />.
/// </remarks>
unit MyLibrary.Collections;

For a type, describe what it represents and when callers should use it. Document every generic type parameter by its declared name:

pascal
/// <summary>
///   Provides a resizable array-backed implementation of
///   <see cref="IList{T}" />.
/// </summary>
/// <typeparam name="T">
///   The type of values in the list.
/// </typeparam>
/// <remarks>
///   This class is the default list implementation returned by the factory
///   methods on <see cref="TCollections" />.
/// </remarks>
TArrayList<T> = class(TInterfacedObject, IList<T>)
end;

Document methods and return values

Describe what the method does, what each parameter means, and how callers should interpret the result. The name on <param> and <typeparam> must match the declaration. Use <paramref> and <typeparamref> when referring to those names in prose:

pascal
/// <summary>
///   Compares two values and returns their relative order.
/// </summary>
/// <param name="Left">
///   The first value to compare.
/// </param>
/// <param name="Right">
///   The second value to compare.
/// </param>
/// <returns>
///   A value less than zero if <paramref name="Left" /> precedes
///   <paramref name="Right" />, zero if they are equal, or a value greater
///   than zero if <paramref name="Left" /> follows <paramref name="Right" />.
/// </returns>
function Compare(const Left, Right: T): Integer;

Document each overload independently. An overload should describe its own parameters, defaults, behavior, and result rather than relying on the comment for another declaration.

Document properties

Use <summary> to describe what the property provides and <value> to describe the value itself. Put ownership rules, mutation behavior, and other constraints in <remarks>:

pascal
/// <summary>
///   Gets a value indicating whether the list owns its objects.
/// </summary>
/// <value>
///   True when the list frees contained objects; otherwise, false.
/// </value>
/// <remarks>
///   Owned objects are freed when they are removed, when the list is cleared,
///   or when the list is destroyed.
/// </remarks>
property OwnsObjects: Boolean read FOwnsObjects;

For an indexed property, use <param> for each index parameter and <value> for the value read or written.

Describe constraints and exceptions

Use <remarks> for behavior that applies beyond the main summary. Use one <exception> for each exception that forms part of the public contract, and describe the condition that raises it:

pascal
/// <summary>
///   Gets the value at the specified index.
/// </summary>
/// <param name="Index">
///   The zero-based index of the value to get.
/// </param>
/// <returns>
///   The value at the specified index.
/// </returns>
/// <exception cref="EArgumentOutOfRangeException">
///   <paramref name="Index" /> is less than zero or greater than or equal to
///   <see cref="IReadOnlyCollection{T}.Count" />.
/// </exception>
function GetItem(Index: Integer): T;

Do not list every implementation exception. Document exceptions that callers can reasonably anticipate and handle.

Add usage examples

Place executable sample code inside <example> and <code>. Set lang="delphi" to enable Delphi syntax highlighting:

pascal
/// <summary>
///   Creates a resizable list of values.
/// </summary>
/// <typeparam name="T">
///   The type of values in the list.
/// </typeparam>
/// <returns>
///   A new <see cref="IList{T}" /> instance.
/// </returns>
/// <example>
///   <code lang="delphi">
///     var
///       Names: IList&lt;string&gt;;
///     begin
///       Names := TCollections.CreateList&lt;string&gt;;
///       Names.AddRange(['Ada', 'Grace']);
///     end;
///   </code>
/// </example>
class function CreateList<T>: IList<T>; static;

Keep examples focused on the declaration being documented. Use realistic names and ensure the sample remains valid when the API changes.

Format documentation text

Use XML elements to add structure and meaning inside documentation sections:

Element

Use for

<para> or <p>

A separate paragraph

<c>

An identifier, literal, or short code expression

<code>

A code block

<paramref>

A reference to a method parameter

<typeparamref>

A reference to a generic type parameter

<see>

An inline link

<list>

A bullet list, numbered list, or table

<note>

A note, tip, warning, or other callout

<b>, <i>, and related elements

Emphasis when wording alone is insufficient

Use formatting sparingly. Prefer clear sentences and short paragraphs over heavily marked-up descriptions. For cref, xref, external links, and local resources, see Link API symbols and topics.

Write well-formed XML

The text in /// comments is parsed as XML. Close every element, quote attribute values, and escape characters that would otherwise be interpreted as markup:

pascal
/// <summary>
///   Returns an <c>IList&lt;T&gt;</c> when A &amp; B are available.
/// </summary>

Use &lt;, &gt;, and &amp; for literal <, >, and & characters in XML content. Delphi generic syntax in the declaration itself remains unchanged.

Check the documentation

Run a documentation check after adding or changing XML comments:

shell
docinsight check

The check reports malformed XML and unresolved cross-references with source locations and corrective guidance. Before publishing, verify that summaries state purpose, parameter names match the declaration, return values and exceptions describe observable behavior, and examples still reflect the current API.