Jak odwoływać się do klas ogólnych i metod w dokumentacji XML

198

Podczas pisania dokumentacji XML można użyć <see cref="something">something</see>, co oczywiście działa. Ale w jaki sposób odwołujesz się do klasy lub metody z typami rodzajowymi?

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

Gdybym miał gdzieś napisać dokumentację XML, jak miałbym odwoływać się do tej wyszukanej klasy? jak mogę odwołać się do FancyClass<string>? Co z metodą?

Na przykład w innej klasie chciałem poinformować użytkownika, że ​​zwrócę instancję FancyClass<int>. Jak mogę zrobić w tym celu coś z krepy?

Svish
źródło

Odpowiedzi:

257

Aby odwołać się do metody:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.
Lasse V. Karlsen
źródło
3
Dzięki za odpowiedź! W rzeczywistości brakuje go na stronie MSDN w <see>: msdn.microsoft.com/en-us/library/acd0tfbe.aspx
joce
6
Naprawdę uważam, że działa również w podpowiedziach VS2010, musisz wskazać liczbę ogólnych argumentów, np. „FancyClass 1{T}.FancyMethod1 {K} (T)”
Stephen Drew,
Nie jestem pewien, co masz na myśli. Nigdy nie musiałem ich dodawać i zawsze działało to dla mnie. Czy masz konkretny przykład, w którym to nie działa? Jeśli tak, prosimy o przesłanie go gdzieś (lub nawet samodzielną odpowiedź).
Lasse V. Karlsen
@Lasse, zobacz odpowiedź Steve'a i komentarze poniżej. Twoja odpowiedź nie obejmuje poprawnych podpowiedzi Intellisense.
Jakub Januszkiewicz
43
/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary>

BTW, był obecny w dokumentacji MSDN .Net Framework 2.0 i 3.0 , ale zniknął w wersji 3.5

thinkbeforecoding
źródło
4
co ze szczególnym przypadkiem T? jak sznurek? Może nie jest to możliwe?
Svish,
co masz na myśli? Nie możesz zadeklarować konkretnej wersji, więc też nie możesz się do niej odwoływać.
Lasse V. Karlsen
Jeśli na przykład metoda zwraca tylko List <ciąg>. Ale nie ważne :)
Svish
7
Tak, zastanawiałem się także ... rekruterzy kłócą się podczas pisania FancyClass {ciąg}, ale nie podczas pisania FancyClass {ciąg} ...
thinkbeforecoding
6
Powodem powyższej obserwacji przez „Think Before Coding” jest to, że nie działa z aliasami c #. Na przykład musisz użyć Int32zamiast int, Singlezamiast floatitp. (Umieszczenie tej informacji tutaj, na wypadek, gdyby ktoś się na nią natknął)
AnorZaken
27

TL; DR:

„Jak mam się odwoływać FancyClass<T>?”

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

„A co z FancyClass<T>.FancyMethod<K>(T value)?”

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

„Jak mogę odwołać się do FancyClass<string>?”

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

Chociaż można odwoływać się do metody, której podpis obejmuje FancyClass<string>(np. Jako typ parametru), nie można bezpośrednio odwoływać się do takiego zamkniętego typu ogólnego. Drugi przykład omija to ograniczenie. (Widać to np. Na stronie refrenowej MSDN dla System.String.Concat(IEnumerable<string>)metody statycznej ). :

crefReguły komentarzy do dokumentacji XML :

  • Otocz listę parametrów typów ogólnych za pomocą nawiasów klamrowych{} zamiast nawiasów<> kątowych. Te części zamienne was od ucieczki ta ostatnia jak &lt;i &gt;- pamiętaj, komentarze dokumentacyjne są XML!

  • Jeśli podasz prefiks (np.T: Dla typów, M:dla metod, P:dla właściwości, F:dla pól), kompilator nie dokona żadnego sprawdzenia poprawności odwołania, ale po prostu skopiuje crefwartość atrybutu bezpośrednio do danych wyjściowych XML dokumentacji. Z tego powodu będziesz musiał użyć specjalnej składni „ciąg identyfikatora”, która ma zastosowanie w takich plikach: zawsze używaj w pełni kwalifikowanych identyfikatorów i użyj odwrotnych znaków , aby odwoływać się do ogólnych parametrów `ntypów ( na typach, ``nna metodach).

  • Jeśli pominiesz prefiks , obowiązują zasady nazywania języka: możesz usunąć przestrzenie nazw, dla których istnieje usinginstrukcja, i możesz użyć słów kluczowych typu, takich jak intzamiast System.Int32. Ponadto kompilator sprawdzi referencję pod kątem poprawności.

Ściągawka z komentarzem do dokumentacji 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 - już nie przyczynia się
źródło
Jak skierować tylko Tczęść?
nawfal
4
<typeparamref name="T"/>
Opracowano
21

Żadna z dotychczas pokazanych odpowiedzi nie działa dla mnie całkowicie. ReSharper nie przekształci tagu see w Ctrllink + możliwy do kliknięcia (np. obraz tutaj), Chyba że zostanie całkowicie rozwiązany.

Gdyby metoda w OP znajdowała się w nazwanej przestrzeni nazw Test, całkowicie rozstrzygnięty link do pokazanej metody to:

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

Ponieważ możesz być w stanie wypracować, powinien być tylko jeden wsteczny przed liczbą parametrów typu klasy, a następnie dwa wsteczne przed liczbą parametrów typu metody, wówczas parametry są parametrem o indeksie zerowym z odpowiednią liczbą wstecznych.

Widzimy więc, że FancyClassma jeden parametr typu klasy, FancyMethodma jeden parametr typu, a obiekt FancyClasstypu parametru zostanie przekazany do metody.

Jak można lepiej zobaczyć w tym przykładzie:

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

Link staje się:

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

Lub „Klasa z parametrami dwa typu, który posiada metodę z trzema parametrami typu gdzie parametry metod są ClassType1, ClassType2, MethodType1, MethodType2, MethodType3


Dodatkowo, nie znalazłem tego udokumentowanego nigdzie i nie jestem geniuszem, kompilator powiedział mi to wszystko. Wszystko, co musisz zrobić, to utworzyć projekt testowy, włączyć dokumentację XML , a następnie wstawić kod, dla którego chcesz wypracować link, i umieścić na nim komentarz XML doc ( ///):

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

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

Następnie skompiluj projekt, a wygenerowana dokumentacja XML zawiera link w elemencie doc-> members-> memberpod atrybutem 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
źródło
3
Powinno to uzyskać więcej głosów pozytywnych, zwłaszcza ze względu na sztuczkę polegającą na znalezieniu poprawnego zapisu, bez konieczności przechodzenia przez próby i błędy. Kudos mój człowieku
Peter,
10

Dalej od odpowiedzi Lasse i TBC:

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

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

będzie także poprawnie wyświetlać podpowiedzi, a ich wersja renderuje je za pomocą nawiasów klamrowych.

Stephen Drew
źródło
2
Korzystając z <patrz 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> - czy chciałbyś się zastanowić, jak tego użyć?
Jakub Januszkiewicz
2
Cześć Jakub, To naprawdę nie działa. Jedynym sposobem na poprawne działanie podpowiedzi jest <patrz cref = "T: <nazwa_typu>` 1 {T} "/>.
Stephen Drew,
2
OK, częściowo to rozumiem. Jeśli sama metoda nie jest ogólna (jak na liście <T> .Add ()), działa to: <patrz cref = "M: System.Collections.Generic.List`1 {T} .Add (T)" /> .
Jakub Januszkiewicz
1
Wydaje się, że nie działa dla mnie. Mam <see cref = "M: System.Collections.Generic.List`1 {T}" /> w nagłówku komentarza do ogólnej metody rozszerzenia, którą napisałem (konwertuje ArrayList na Listę <T>), ale ReSharper zaznacza ją jako błąd składniowy, a IntelliSense wyświetla go dosłownie. VS 2010 / R # 6.1.37.86
Mike Loux
8
Aha! Byłem w stanie uzyskać <see cref = "T: System.Collections.Generic.List`1" /> " do pracy. Tak więc, używając T: zamiast nawiasów klamrowych załatwiłem sprawę . Rozszerza pełną przestrzeń nazw, a sztuczka nie działa, jeśli nie uwzględnisz przestrzeni nazw, więc nie jest idealna, ale się uda
Mike Loux 16.01.2013
5
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
JohnL4
źródło
3
Zauważ, że inne odpowiedzi obejmują sposób odwoływania się do klasy ogólnej, ta odpowiedź pokazuje, jak samodzielnie odwoływać się do parametru type, co było właśnie tym, co chciałem zrobić.
jrh
1
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.
Max Toro
źródło