簡體   English   中英

如何在 xml 文檔中引用泛型類和方法

[英]How to reference generic classes and methods in xml documentation

在編寫 xml 文檔時,您可以使用<see cref="something">something</see> ,這當然有效。 但是如何引用具有泛型類型的類或方法呢?

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

如果我要在某處編寫 xml 文檔,我將如何引用這個花哨的類? 我如何引用FancyClass<string> 方法呢?

例如,在另一個類中,我想讓用戶知道我將返回FancyClass<int>一個實例。 我怎么能為此做一個查看 cref 的東西?

要引用該方法:

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

順便說一句,它出現在.Net Framework 2.03.0的 MSDN 文檔中,但它在3.5 版中消失了

特爾;博士:

“我將如何引用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> (例如,作為參數類型),則不能引用這樣的直接關閉通用類型。 第二個示例解決了該限制。 (這可以在靜態System.String.Concat(IEnumerable<string>)方法MSDN 參考頁面上看到)。

XML 文檔注釋cref規則:

  • 用大括號{}而不是<>尖括號將泛型類型參數列表括起來。 這使您免於將后者轉義為&lt; &gt; — 請記住,文檔注釋是 XML!

  • 如果包含前綴(例如T:表示類型, M:表示方法, P:表示屬性, F:表示字段),編譯器不會對引用執行任何驗證,而只是將cref屬性值直接復制到文檔 XML 輸出。 因此,您必須使用適用於此類文件的特殊“ID 字符串”語法:始終使用完全限定的標識符,並使用反引號引用泛型類型參數( `n在類型上, ``n在方法上) .

  • 如果省略 prefix ,則適用常規語言命名規則:您可以刪除有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);
    }
}

到目前為止顯示的答案都沒有完全適合我。 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)

或“具有兩個類型參數的類,該類具有具有三個類型參數的方法,其中方法參數為ClassType1ClassType2MethodType1MethodType2MethodType3


作為附加說明,我沒有在任何地方找到這方面的記錄,而且我也不是天才,編譯器告訴了我這一切。 您所要做的就是創建一個測試項目, 啟用 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 文檔在屬性name下的doc -> members -> member元素中包含鏈接:

<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Test</name>
    </assembly>
    <members>
        <member name="M:Test.FancyClass`1.FancyMethod``1(`0)">

        </member>
    </members>
</doc>

進一步來自 Lasse 和 TBC 的回答:

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

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

還將正確提供工具提示,而他們的版本則使用花括號呈現它。

/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.

這是我在別處給出的答案。 它也適用於類和方法。

我嘗試了堆棧溢出的所有方法,以獲得在幾種情況下都有效的結果。 這是一個對我有用的解決方案。 (關於其他人,這是主觀的。)

  1. 產生可點擊的鏈接。
  2. 將鼠標懸停在標識符上有效。
  3. 正確生成 .xml 文件。
  4. 在智能感知中不會產生錯誤。
  5. 適用於可為空的泛型類型參數。
  6. 在 Resharper 中工作,它是內置的 XML Doc 窗口(Resharper -> 編輯 -> 顯示快速文檔)
  7. 適用於 Atomineer Pro Documentaion Visual Studio Extension 的 XAM Doc Preview。
  8. 使用泛型類型的泛型類型。

示例#1

  /// <summary>
  ///  This instance field holds a reference to the
  ///  <see cref="ConcurrentDictionary{Decimal, Boolean}"/> as
  ///  <see cref="T:ConcurrentDictionary&lt;decimal, bool?&gt;"/> that contains
  ///  the list of all PDF's that are currently opened and being displayed.
  /// </summary>
  private ConcurrentDictionary<decimal, bool?> openedPdfs = default!;

  Note: 
    The ConcurrentDictionary{Decimal, Boolean} will correctly produce a
    clickable link of ConcurrentDictionary{TKey, TValue} on hovering while
    T:ConcurrentDictionary&lt;decimal, bool?&gt; makes sure the reader gets
    information on what type TKey and TValue are.

示例#2(使用“T”)

  /// <summary>
  ///  This instance field holds a reference to the
  ///  <see cref="ConcurrentDictionary{TKey, TValue}"/> as
  ///  <see cref="T:ConcurrentDictionary&lt;decimal, bool?&gt;"/> that contains
  ///  the list of all PDF's that are currently opened and being displayed.
  /// </summary>
  private ConcurrentDictionary<decimal, bool?> openedPdfs = default!;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM