Cómo hacer referencia a clases y métodos genéricos en documentación xml


Al escribir documentación xml puede usar <see cref="something">something</see>, que funciona por supuesto. Pero, ¿cómo se hace referencia a una clase o un método con tipos genéricos?

public class FancyClass<T>
{
  public string FancyMethod<K>(T value) { return "something fancy"; }
}

Si fuera a escribir documentación xml en algún lugar, ¿cómo haría referencia a la clase fancy? ¿cómo puedo hacer referencia a FancyClass<string>? ¿Y el método?

Por ejemplo, en una clase diferente quería hacerle saber al usuario que devolveré una instancia de FancyClass<int>. ¿Cómo podría hacer una cosa de See Cref por eso?

Author: John Saunders, 2009-02-10

7 answers

Para hacer referencia al método:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.
 231
Author: Lasse Vågsæther Karlsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-10 13:01:18
/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary>

Por CIERTO, estaba presente en la documentación de MSDN de .Net Framework 2.0 y 3.0, pero desapareció en el versión 3.5

 41
Author: thinkbeforecoding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-10 16:30:54

Ninguna de las respuestas mostradas hasta ahora funciona completamente para mí. ReSharper no convertirá la etiqueta see en un enlace Ctrl + clickable (p. ej. imagen aquí) a menos que se resuelva completamente.

Si el método en el OP estuviera en un espacio de nombres llamado Test, el enlace completamente resuelto al método mostrado sería:

<see cref="M:Test.FancyClass`1.FancyMethod``1(`0)"/>

Como puede ser capaz de trabajar, solo debe haber un backtick antes del número de parámetros de tipo de clase, luego dos backticks antes del número de tipo de método parámetros, entonces los parámetros son el parámetro 0-indexado con el número apropiado de retroiluminación.

Así que podemos ver que FancyClass tiene 1 parámetro de tipo de clase, FancyMethod tiene un parámetro de tipo, y un objeto del tipo de parámetro FancyClass se pasará al método.

Como se puede ver más claramente en este ejemplo:

namespace Test
{
    public class FancyClass<A, B>
    {
        public void FancyMethod<C, D, E>(A a, B b, C c, D d, E e) { }
    }
}

El enlace se convierte en:

M:Test.FancyClass`2.FancyMethod``3(`0,`1,``0,``1,``2)

O ' Class with 2 type parameters que tiene un method with 3 type parameters donde los parámetros del método son ClassType1, ClassType2, MethodType1, MethodType2, MethodType3)


Como nota adicional, no encontré esto documentado en ninguna parte y no soy un genio, el compilador me dijo todo esto. Todo lo que tiene que hacer es crear un proyecto de prueba, habilitar la documentación XML , luego insertar el código para el que desea elaborar un enlace y poner el inicio de un comentario XML doc en él (///):

namespace Test
{
    public class FancyClass<T>
    {
        ///
        public string FancyMethod<K>(T value) { return "something fancy"; }
    }

    public class Test
    {
        public static void Main(string[] args) { }
    }
}

Luego compile su proyecto, y la documentación XML de salida incluye el enlace en el doc->members->member elemento bajo el atributo name:

<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Test</name>
    </assembly>
    <members>
        <member name="M:Test.FancyClass`1.FancyMethod``1(`0)">

        </member>
    </members>
</doc>
 15
Author: MrLore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-10 17:37:04

TL; DR: {[26]]}

"¿Cómo haría referencia a FancyClass<T>?"

   /// <see cref="FancyClass{T}"/>

"¿Qué pasa con FancyClass<T>.FancyMethod<K>(T value)?"

   /// <see cref="FancyClass{T}.FancyMethod{K}(T)"/>

"¿Cómo puedo hacer referencia a FancyClass<string>?"

   /// <see cref="SomeType.SomeMethod(FancyClass{string})"/>
   /// <see cref="FancyClass{T}"/> whose generic type argument is <see cref="string"/>

Mientras que puede hacer referencia a un método cuya firma incluye FancyClass<string> (por ejemplo, como un tipo de parámetro), no puede hacer referencia a un tipo genérico cerrado directamente. El segundo ejemplo funciona alrededor de esa limitación. (Esto se ve por ejemplo en la página de referencia MSDN para el método estático System.String.Concat(IEnumerable<string>) ). :

Comentario de documentación XML cref reglas:

  • Rodee la lista de parámetros de tipo genérico con llaves {} en lugar de con <> corchetes angulares. Esto le evita escapar de este último como &lt; y &gt; - recuerde, los comentarios de la documentación son XML!

  • Si incluye un prefijo (como T: para tipos, M: para métodos, P: para propiedades, F: para los campos), el compilador no realizará ninguna validación de la referencia, sino que simplemente copiará el valor del atributo cref directamente en la salida XML de la documentación. Por esta razón, tendrá que usar la sintaxis especial "ID string" que se aplica en dichos archivos: siempre use identificadores completos y use retroiluminación para hacer referencia a parámetros de tipo genéricos (`n en tipos, ``n en métodos).

  • Si omite el prefijo , las reglas de nomenclatura del idioma aplicar: puede eliminar espacios de nombres para los que hay una instrucción using, y puede usar palabras clave del tipo del idioma, como int en lugar de System.Int32. Además, el compilador comprobará la corrección de la referencia.

XML documentation comment cref cheat sheet:

namespace X
{
    using System;

    /// <see cref="I1"/>  (or <see cref="X.I1"/> from outside X)
    /// <see cref="T:X.I1"/>
    interface I1
    {
        /// <see cref="I1.M1(int)"/>  (or <see cref="M1(int)"/> from inside I1)
        /// <see cref="M:X.I1.M1(System.Int32)"/>
        void M1(int p);

        /// <see cref="I1.M2{U}(U)"/>
        /// <see cref="M:X.I1.M2``1(``0)"/>
        void M2<U>(U p);

        /// <see cref="I1.M3(Action{string})"/>
        /// <see cref="M:X.I1.M3(System.Action{System.String})"/>
        void M3(Action<string> p);
    }

    /// <see cref="I2{T}"/>
    /// <see cref="T:X.I2`1"/>
    interface I2<T>
    {
        /// <see cref="I2{T}.M1(int)"/>
        /// <see cref="M:X.I2`1.M1(System.Int32)"/>
        void M1(int p);

        /// <see cref="I2{T}.M2(T)"/>
        /// <see cref="M:X.I2`1.M2(`0)"/>
        void M2(T p);

        /// <see cref="I2{T}.M3{U}(U)"/>
        /// <see cref="M:X.I2`1.M3``1(``0)"/>
        void M3<U>(U p);
    }
}
 11
Author: stakx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-18 15:00:06

Más allá de las respuestas de Lasse y T. B. C:

/// <see cref="T:FancyClass`1{T}"/> for more information.

/// <see cref="M:FancyClass`1{T}.FancyMethod`1{K}(T)"/> for more information.

También proporcionará información sobre herramientas correctamente, mientras que su versión lo renderiza con las llaves.

 9
Author: Stephen Drew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-10 17:14:22
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
 2
Author: JohnL4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-10 15:54:16
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.
 1
Author: Max Toro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-28 15:25:26