Как ссылаться на общие классы и методы в документации XML

198

При написании XML-документации вы можете использовать <see cref="something">something</see>, что, конечно, работает. Но как вы ссылаетесь на класс или метод с универсальными типами?

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

Если бы я собирался написать где-нибудь документацию xml, как бы я сослался на причудливый класс? как я могу сослаться наFancyClass<string> ? Как насчет метода?

Например, в другом классе я хотел, чтобы пользователь знал, что я верну экземпляр FancyClass<int>. Как я могу сделать что-нибудь для этого?

Svish
источник

Ответы:

257

Для ссылки на метод:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.
Лассе В. Карлсен
источник
3
Спасибо за этот ответ! Это на самом деле отсутствует странице MSDN по <см>: msdn.microsoft.com/en-us/library/acd0tfbe.aspx
Joce
6
Я действительно считаю, что он также работает в подсказках VS2010, вам нужно указать количество общих аргументов, например, «FancyClass 1{T}.FancyMethod1 {K} (T)»
Стивен Дрю,
Не уверен, что ты имеешь в виду. Я никогда не должен был добавлять их, и это всегда работало для меня. У вас есть конкретный пример, где это не работает? Если это так, пожалуйста, опубликуйте это где-нибудь (или даже предоставьте ответ самостоятельно.)
Лассе В. Карлсен
@Lasse, см. Ответ Стива и комментарии ниже. Ваш ответ не охватывает правильные подсказки Intellisense.
Якуб Янушкевич
43
/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary>

Кстати, он присутствовал в документации MSDN .Net Framework 2.0 и 3.0 , но исчез в версии 3.5

thinkbeforecoding
источник
4
как насчет особого случая T? как строка? Может быть, не возможно?
Свиш
что вы имеете в виду? Вы не можете объявить конкретную версию, поэтому вы также не можете ссылаться на нее.
Лассе В. Карлсен
Например, если метод возвращает только List <string>. Но не важно :)
Свиш
7
Да, мне было интересно также ... резкие изменения при написании FancyClass {string}, но не при написании FancyClass {String} ...
thinkbeforecoding
6
Причиной вышеупомянутого наблюдения со стороны «Think Before Coding» является то, что он не работает с псевдонимами c #. Например, вам нужно использовать Int32вместо int, Singleвместо, floatи т. Д. (Поместить эту информацию здесь на случай, если кто-то еще
наткнется
27

TL; DR:

"Как бы я сослался FancyClass<T>?"

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

"Как насчет FancyClass<T>.FancyMethod<K>(T value)?"

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

"Как я могу ссылаться на FancyClass<string>?"

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

Хотя вы можете ссылаться на метод, чья сигнатура включает FancyClass<string>(например, в качестве типа параметра), вы не можете напрямую ссылаться на такой закрытый универсальный тип. Второй пример работает вокруг этого ограничения. (Это видно, например, на странице ссылки MSDN для статического System.String.Concat(IEnumerable<string>)метода ). :

crefПравила комментирования XML-документации :

  • Обведите список параметров универсального типа фигурными скобками,{} а не <>угловыми скобками. Это избавит вас от возможности избежать последнего, поскольку &lt;и &gt;- помните, комментарии к документации в формате XML!

  • Если вы включите префикс (например,T: для типов, M:для методов, P:для свойств, F:для полей), компилятор не будет выполнять проверку ссылки, а просто скопирует crefзначение атрибута прямо в вывод XML документации. По этой причине вам придется использовать специальный синтаксис «строка идентификатора», который применяется в таких файлах: всегда использовать полностью определенные идентификаторы и использовать обратные ссылки для ссылки на параметры универсального типа ( `nдля типов, ``nдля методов).

  • Если вы пропустите префикс , применяются обычные правила именования языков: вы можете отбросить пространства имен, для которых есть usingоператор, и можете использовать ключевые слова типа языка, например intвместо System.Int32. Также компилятор проверит ссылку на правильность.

Шпаргалка с комментариями к документации XML cref:

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 - больше не помогает
источник
Как передать только Tчасть?
Nawfal
4
<typeparamref name="T"/>
Выяснил
21

Ни один из приведенных ответов не работает для меня полностью. ReSharper не будет преобразовывать тег see в Ctrlссылку + click -able (например,изображение здесь ), пока он полностью не разрешится.

Если бы метод в OP находился в вызванном пространстве имен Test, полностью разрешенная ссылка на показанный метод была бы:

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

Как вы можете выяснить, перед числом параметров типа класса должен быть только один обратный трюк, затем два обратных тика перед числом параметров типа метода, тогда параметры являются индексированным параметром с нулевым индексом и соответствующим количеством обратных токов.

Таким образом, мы можем видеть, что FancyClassимеет один параметр типа класса, FancyMethodимеет один параметр типа и объектFancyClass параметра будет передан методу.

Как вы можете видеть более ясно в этом примере:

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

Ссылка становится:

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

Или «Класс с параметрами два типа , который имеет метод с тремя параметрами типа , где параметры метода ClassType1, ClassType2, MethodType1, MethodType2, MethodType3»


Как дополнительное примечание, я нигде не нашел этого документированного, и я не гений, компилятор сказал мне все это. Все, что вам нужно сделать, это создать тестовый проект, включить XML-документацию , затем вставить код, для которого вы хотите разработать ссылку, и поместить в него начало XML-документа ( ///):

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

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

Затем создайте свой проект, и выводимая документация XML будет содержать ссылку в элементе doc-> members-> memberпод атрибутом 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
источник
3
Это должно получить больше голосов, особенно из-за уловки, чтобы найти правильную запись, без необходимости проб и ошибок. Престижность моего мужчины
Питер
10

Далее из ответов Лассе и TBC:

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

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

также будет правильно отображать всплывающие подсказки, в то время как их версия отображает фигурные скобки.

Стивен Дрю
источник
2
Использование <see cref = "System.Collections.Generic.List1{T}"/>** causes a build-time warning: **XML comment on 'Blah' has syntactically incorrect cref attribute 'System.Collections.Generic.List 1 <T> - не могли бы вы уточнить, как это можно использовать?
Якуб Янушкевич,
2
Привет Якуб, это действительно не похоже на работу. Единственный способ заставить подсказки работать правильно - это <see cref = "T: <fullTypeName>` 1 {T} "/>.
Стивен Дрю
2
Хорошо, я частично получил это. Если сам метод не является универсальным (как в List <T> .Add ()), это работает: <see cref = "M: System.Collections.Generic.List`1 {T} .Add (T)" /> ,
Якуб Янушкевич
1
Кажется, не работает для меня. У меня есть <see cref = "M: System.Collections.Generic.List`1 {T}" /> в заголовке комментария для общего метода расширения, который я написал (преобразует ArrayList в List <T>), но ReSharper помечает его как синтаксическая ошибка, и IntelliSense просто отображает ее дословно. VS 2010 / R # 6.1.37.86
Майк Лу
8
Ага! Мне удалось заставить <see cref = "T: System.Collections.Generic.List`1" /> " работать. Таким образом, с помощью T: вместо фигурных скобок получилось. Это действительно расширяет полное пространство имен, и трюк не сработает, если вы не включите пространство имен, поэтому он не идеален, но сработает
Майк Лукс
5
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
JohnL4
источник
3
Обратите внимание, что другие ответы касаются того, как ссылаться на общий класс, этот ответ показывает вам, как ссылаться на параметр типа самостоятельно, что я и хотел сделать.
JRH
1
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.
Макс Торо
источник