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

198

Al escribir documentación xml puede usar <see cref="something">something</see>, lo que funciona, por supuesto. Pero, ¿cómo 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 iba a escribir documentación xml en alguna parte, ¿cómo haría referencia a la clase elegante? ¿Cómo puedo hacer referencia a un FancyClass<string>? ¿Qué hay del método?

Por ejemplo, en una clase diferente, quería que el usuario supiera que devolveré una instancia de FancyClass<int>. ¿Cómo podría hacer una cosa ver cref para eso?

Svish
fuente

Respuestas:

257

Para hacer referencia al método:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.
Lasse V. Karlsen
fuente
3
Gracias por esa respuesta! En realidad, falta en la página de MSDN en <ver>: msdn.microsoft.com/en-us/library/acd0tfbe.aspx
joce
66
De hecho, creo que para que funcione también en la información sobre herramientas de VS2010, debe indicar el número de argumentos genéricos, por ejemplo, "FancyClass 1{T}.FancyMethod1 {K} (T)"
Stephen Drew
No estoy seguro de lo que quieres decir con eso. Nunca he tenido que agregarlos, y siempre me ha funcionado. ¿Tienes un ejemplo específico donde no funciona? Si es así, publíquelo en algún lugar (o incluso proporcione una respuesta usted mismo).
Lasse V. Karlsen
@Lasse, vea la respuesta y los comentarios de Steve a continuación. Su respuesta no cubre información sobre herramientas correctas de Intellisense.
Jakub Januszkiewicz
43
/// <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 la versión 3.5

pensar antes de codificar
fuente
44
¿Qué pasa con una instancia específica de T? como una cuerda? Tal vez no es posible?
Svish
¿Qué quieres decir? No puede declarar una versión específica, por lo que tampoco puede hacer referencia a ella.
Lasse V. Karlsen
Si un método, por ejemplo, solo devuelve List <string>, por ejemplo. Pero no es importante :)
Svish
77
Sí me preguntaba también ... resharpers garabatos al escribir FancyClass {cadena} pero no al escribir FancyClass {String} ...
thinkbeforecoding
66
La razón de la observación anterior de "Think Before Coding" es que no funciona con los alias c #. Por ejemplo, debe usar en Int32lugar de int, en Singlelugar de floatetc. (Poner esta información aquí en caso de que alguien más se tropiece con esto)
AnorZaken
27

TL; DR:

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

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

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

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

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

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

Si bien puede hacer referencia a un método cuya firma incluye FancyClass<string>(por ejemplo, como un tipo de parámetro), no puede 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 de MSDN para el System.String.Concat(IEnumerable<string>)método estático ). :

Comentario de documentación XML crefReglas de :

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

  • Si incluye un prefijo (comoT: para tipos, M:métodos, P:propiedades, F:campos), el compilador no realizará ninguna validación de la referencia, sino que simplemente copiará el crefvalor del atributo directamente a la salida XML de la documentación. Por esta razón, tendrá que usar la sintaxis especial de "cadena de ID" que se aplica en dichos archivos: use siempre identificadores totalmente calificados y use las teclas de retroceso para hacer referencia a parámetros de tipo genérico ( `nen tipos, ``nen métodos).

  • Si omite el prefijo , se aplicarán las reglas de nomenclatura de idiomas habituales: puede colocar espacios de nombres para los que hay unusing declaración y puede usar las palabras clave de tipo de idioma como en intlugar de System.Int32. Además, el compilador verificará que la referencia sea correcta.

Documentación XML comentario crefhoja de trucos:

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);
    }
}
stakx - ya no contribuye
fuente
¿Cómo referir solo la Tparte?
nawfal
44
<typeparamref name="T"/>
Descubierto
21

Ninguna de las respuestas mostradas hasta ahora funciona completamente para mí. ReSharper no convertirá la etiqueta ver en un Ctrlenlace que pueda hacer clic con un clic (p. Ej.imagen aqui ) a menos que se resuelva por completo.

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 es posible que pueda resolver, solo debe haber un retroceso antes del número de parámetros de tipo de clase, luego dos retrocesos antes del número de parámetros de tipo de método, luego los parámetros son el parámetro indexado a cero con el número apropiado de retrocesos.

Entonces podemos ver que FancyClasstiene un parámetro de tipo de clase, FancyMethodtiene un parámetro de tipo y un objeto deFancyClass parámetro de tipo y se pasará tipo de parámetro al método.

Como 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 "Clase con dos parámetros de tipo, que tiene un método con tres parámetros de tipo, 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 contó 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 comienzo de un comentario de documento XML 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 construya su proyecto, y la documentación XML resultante incluye el enlace en el elemento doc-> members-> memberdebajo del 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>
MrLore
fuente
3
Esto debería obtener más votos positivos, especialmente debido al truco para encontrar la notación correcta, sin tener que pasar por prueba y error. Felicitaciones a mi hombre
Peter
10

Más allá de las respuestas de Lasse y TBC:

/// <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 representa con las llaves.

Stephen Drew
fuente
2
Usando <see cref = "System.Collections.Generic.List 1{T}"/>** causes a build-time warning: **XML comment on 'Blah' has syntactically incorrect cref attribute 'System.Collections.Generic.List1 <T> - ¿Le gustaría explicar cómo se debe usar esto?
Jakub Januszkiewicz
2
Hola Jakub, esto no parece funcionar. La única forma en que también puedo obtener información sobre herramientas para que funcione correctamente es mediante <see cref = "T: <fullTypeName>` 1 {T} "/>.
Stephen Drew
2
OK, lo entendí parcialmente. Si el método en sí no es genérico (como en List <T> .Add ()), esto funciona: <see cref = "M: System.Collections.Generic.List`1 {T} .Add (T)" /> .
Jakub Januszkiewicz
1
No parece estar funcionando para mí. Tengo <see cref = "M: System.Collections.Generic.List`1 {T}" /> en el encabezado del comentario para un método de extensión genérico que escribí (convierte una ArrayList en una Lista <T>) pero ReSharper lo marca como un error de sintaxis, e IntelliSense solo lo muestra textualmente. VS 2010 / R # 6.1.37.86
Mike Loux
8
¡Ajá! Pude hacer que <see cref = "T: System.Collections.Generic.List`1" /> " funcionara. Entonces, usar T: en lugar de las llaves hizo el truco. Se expande el espacio de nombres completo, y el truco no funciona si no se incluye el espacio de nombres, por lo que no es perfecto, pero lo hará.
Mike Loux
5
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
JohnL4
fuente
3
Tenga en cuenta que las otras respuestas cubren cómo hacer referencia a una clase genérica, esta respuesta le muestra cómo hacer referencia al parámetro de tipo por sí mismo, que resultó ser lo que estaba buscando hacer.
jrh
1
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.
Max Toro
fuente