2009-02-10 16 views
163

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

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

Si iba a escribir documentación xml en algún lugar, ¿cómo haría referencia a la clase de lujo? ¿Cómo puedo hacer referencia a FancyClass<string>? ¿Qué hay del método?

Por ejemplo, en una clase diferente que quería que el usuario sepa que voy a devolver una instancia de FancyClass<int>. ¿Cómo podría hacer una criba para eso?

+0

(Desplácese hacia abajo para mi respuesta a esta cuestión de edad de 7 años.) – JohnL4

Respuesta

220

Para hacer referencia al método:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information. 
+0

¡Gracias por esa respuesta! En realidad, falta en la página de MSDN en : http://msdn.microsoft.com/en-us/library/acd0tfbe.aspx – joce

+5

Creo que para que también funcione en la información sobre herramientas VS2010 debe indicar el número de argumentos genéricos, p.ej "FancyClass'1 {T} .FancyMethod'1 {K} (T)" –

+0

No estoy seguro de lo que quiere decir al respecto. Nunca tuve que agregarlos, y siempre me ha funcionado. ¿Tienes un ejemplo específico donde no funciona? Si es así, publíquelo en alguna parte (o incluso proporcione una respuesta). –

40
/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary> 

BTW, que estaba presente en la documentación de MSDN de .Net Framework 2.0 y 3.0, pero disapeared en el version 3.5

+2

¿qué pasa con una instancia spesific de T? como una cuerda? Quizás no sea posible? – Svish

+0

¿qué quieres decir? No puede declarar una versión específica, por lo que tampoco puede referirse a ella. –

+0

Si un método, por ejemplo, solo devuelve la lista , por ejemplo. Pero no es importante :) – Svish

9

Además de las respuestas por 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.

+1

Usando ** ** causa una advertencia de tiempo de compilación: ** El comentario XML sobre 'Blah' tiene un atributo de credo sintácticamente incorrecto 'System.Collections .Generic.List'1 ** - ¿Le gustaría explicar cómo debería uno usar esto? –

+2

Hola Jakub, Esto parece no funcionar. La única forma en que también puedo obtener información sobre herramientas para que funcione correctamente es mediante . –

+0

gracias, todo funciona correctamente ahora. Tanto T: como el número explícito (¡y correcto!) De parámetros genéricos son necesarios para compilar sin advertencias y tener información sobre herramientas correcta de Intellisense. Por favor, actualice su respuesta, estaré encantado de votarla, ya que es la más completa de todas. Por cierto, todavía tengo que ver cómo se ve esto después de que la documentación se compila en HTML/lo que sea. –

1
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information. 
12

Ninguna de las respuestas mostradas hasta ahora funciona completamente para mí. ReSharper no convertirá la etiqueta see en un enlace Ctrl + clic (por ejemplo, image here) a menos que se resuelva por completo.

Si el método en el PO se encontraban en un espacio de nombres llamado Test, el enlace resuelto por completo con el método mostrado sería:

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

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

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 una 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 contó todo esto.Todo lo que tiene que hacer es crear un proyecto de prueba, enable XML documentation, a continuación, inserte el código que desea llegar a un enlace para, y puso el comienzo de un comentario de documentación 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 construir el proyecto y la documentación emitida XML incluye el enlace en la 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> 
+2

Esto debería recibir más votos ascendentes, especialmente debido al truco para encontrar la notación correcta, sin tener que ir a prueba y error. Kudos mi hombre – Peter

1
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>. 
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam> 
7

TL; DR:

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

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

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

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

"¿Cómo se puede hacer referencia a que una FancyClass<string>?"

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

Mientras puede referencia un método cuya firma incluye FancyClass<string> (por ejemplo, como un tipo de parámetro), que no puede referencia un tipo genérico tal cerrado directamente. El segundo ejemplo funciona alrededor de esa limitación. (Esto se ve, por ejemplo, en el MSDN refence page for the static System.String.Concat(IEnumerable<string>) method). :

XML documentación comentario cref reglas:

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

  • Si incluye un prefijo (como T: de tipos, M: de métodos, P: de propiedades, F: para los campos), el compilador no realizará ninguna validación de la referencia, sino simplemente copiar el valor cref atributo directamente a la documentación de salida XML. Por este motivo, deberá usar el número especial "ID string" syntax que se aplica en dichos archivos: utilice siempre identificadores totalmente calificados y utilice los respaldos para hacer referencia a los parámetros de tipo genérico (`n en los tipos, ``n en los métodos).

  • Si se omite el prefijo, se aplican las reglas habituales de nomenclatura lenguaje: se puede eliminar espacios de nombres para el que no hay una declaración using, y se puede utilizar palabras clave de tipo del lenguaje tales como int en lugar de System.Int32. Además, el compilador verificará la corrección de la referencia.

XML documentación comentario cref hoja 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); 
    } 
} 
Cuestiones relacionadas