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?

Odpowiedzi:


257

Aby odwołać się do metody:

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

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


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);
    }
}

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>

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.


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>

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.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.