[英]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.0和3.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 參考頁面上看到)。 :
cref
規則: 用大括號{}
而不是<>
尖括號將泛型類型參數列表括起來。 這使您免於將后者轉義為<
和>
— 請記住,文檔注釋是 XML!
如果包含前綴(例如T:
表示類型, M:
表示方法, P:
表示屬性, F:
表示字段),編譯器不會對引用執行任何驗證,而只是將cref
屬性值直接復制到文檔 XML 輸出。 因此,您必須使用適用於此類文件的特殊“ID 字符串”語法:始終使用完全限定的標識符,並使用反引號引用泛型類型參數( `n
在類型上, ``n
在方法上) .
如果省略 prefix ,則適用常規語言命名規則:您可以刪除有using
語句的命名空間,並且可以使用語言的類型關鍵字,例如int
而不是System.Int32
。 此外,編譯器將檢查引用的正確性。
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)
或“具有兩個類型參數的類,該類具有具有三個類型參數的方法,其中方法參數為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 文檔在屬性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<T>.FancyMethod<K>(T)"/> for more information.
這是我在別處給出的答案。 它也適用於類和方法。
我嘗試了堆棧溢出的所有方法,以獲得在幾種情況下都有效的結果。 這是一個對我有用的解決方案。 (關於其他人,這是主觀的。)
示例#1
/// <summary>
/// This instance field holds a reference to the
/// <see cref="ConcurrentDictionary{Decimal, Boolean}"/> as
/// <see cref="T:ConcurrentDictionary<decimal, bool?>"/> 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<decimal, bool?> 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<decimal, bool?>"/> 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.