在C#的XML文档中如何引用一个泛型类型的泛型类型?

47

我正在为一个谓词帮助类编写一些 XML 文档。但是我无法弄清楚如何在不出现语法错误的情况下引用 Expression<Func<T, bool>>。这是否可能?我尝试过以下代码:

<see cref="Expression{Func{T, bool}}"/>

但是在{T, bool}}下面我会看到一个红色的波浪线。不过这个可以正常工作:

<see cref="Expression{TDelegate}"/>

有人知道吗?


更新:

所给出的答案(并被我接受)似乎确实有效。但现在我开始收到很多关于无法解决的警告。我有一个名为ExpressionBuilder<T>的类,它经常与Expression<Func<T,bool>>一起使用。因此,我当然希望在我的XML注释中引用它。

我已经尝试了我所知道的两个版本:

<see cref="Expression&lt;Func&lt;T, Boolean&gt;&gt;"/>
<see cref="Expression{Func{T, Boolean}}"/>

但是两个都不起作用。(在最后一个示例中,ReSharper在{T,Boolean}}下方放置了一个蓝色的波浪线。我在使用它的每个地方都会收到两个编译警告,其中一个说:

  1. XML注释'blah blah'的cref属性'Expression>'无法解析
  2. 类型参数声明必须是标识符而不是类型。另请参见错误CS0081。

在我尝试引用Range<Nullable<DateTime>>Range<DateTime?>也不起作用。无论是使用{ }还是&lt; &gt;),我遇到了相同的问题。

我不能引用这些类型的泛型吗?


2
我正想问同样的问题。由于标题不太具有关键字性,所以我花了一些时间才找到这个。我能否建议使用“如何在C# XML文档中引用通用类型的通用类型”?您还可以添加“泛型”标签。我没有足够的声望来自己完成它。 - Rory MacLeod
<see cref="Expression{Func{T, Boolean}}"/> 在 VS2015 和 Resharper 9 中运行良好。 - Alex
该消息表示“类型参数声明必须是标识符而不是类型”; 例如,如果您有List{Int32},则应为List{T},因为在代码库中没有实际的List{Int32}类存在,只有一个List{T}Int32是一种类型,而T是一个标识符。 - BrainSlugs83
7个回答

49

在XML文档中似乎没有办法引用任何特定类型的泛型,因为实际上,没有办法引用任何特定类型的泛型。

Lasse V Karlsen的答案让我恍然大悟:

如果你写<see cref="IEnumerable{Int32}" />,编译器只使用“Int32”作为类型参数名称,而不是类型参数。写<see cref="IEnumerable{HelloWorld}" />同样也可以。这是有道理的,因为MSDN上没有针对“int的IEnumerable”的具体页面,你的文档无法链接到该页面。

为了正确地记录您的类,我认为您需要编写以下内容:

<summary>
Returns an <see cref="IEnumerable{T}" /> of <see cref="KeyValuePair{T,U}" /> 
of <see cref="String" />, <see cref="Int32" />.
</summary>

我希望这段文字对您有帮助。


5
不,我讨厌文字,这就是我问这个问题的原因。哦好吧...也许在将来的xml-doc版本中会有改善 :p - Svish
3
很遗憾,到了2020年,情况依然没变,这似乎仍是唯一可行的解决方案。依然无法在 cref XML 注释中引用泛型类型,比如 Nullable<int> - DvS

12

你希望它链接到什么地方?

文档中没有类似 Expression<Func<T>> 的东西,所以显然不能链接到它。

可以链接到 Expression<TDelegate>,因为它是存在的。

至于什么起作用或不起作用,以下两者在我的 Visual Studio 2008 / .NET 3.5 中都不起作用:

/// <see cref="Expression&lt;Func&lt;T&gt;&gt;"/>.
/// <see cref="Expression{Func{T}}"/>.

但这个可以运行:
/// <see cref="Expression{T}"/>.

显然,一般类型参数不必与声明中的类型相同。


那么有没有办法用特定类型参数引用通用类型呢?比如,如果我有一个返回List<Func<T,bool>>的函数,我只能说它返回了一个List<T>吗? - Svish
2
那是因为“String”只是用作通用类型名称。尝试使用List<DOOBIEDOOBIEDOO>,它也会同样有效。 - Lasse V. Karlsen

3
不要使用空的see元素(<see cref="..." />)。相反,将文本放置在see元素内部。
<see cref="IEnumerable{T}">IEnumerable</see>&lt;<see cref="..."/>&gt;

正是我想要的。你能修复一下错别字吗?只需将“$gt;”替换为“>”。 - golden96371

3
// Use "&lt;" instead of "<" symbol and "&gt;" instead of ">" symbol.

// Sample:

<see cref="Expression&lt;Func&lt;T, bool&gt;&gt;"/>

哦,我的天啊...这太丑了...但它确实能工作 =/ 为什么它可以接受一个类型的 { },但不能接受更多呢? - Svish
1
确定什么?就像我说的,当使用Expression{TDelegate}或者例如List{String}时,我没有看到任何红色波浪线。实际上,当我输入<see并按下回车键时,它会自动完成为<see cref=""/>。然后我再输入List并按下回车键,它会自动完成为List{T}。 - Svish
2
请注意,红色波浪线不是Visual Studio本身的问题,很可能是ReSharper或者Refactor!Pro等插件引起的。有时它们也会产生混淆。请相信编译器本身。 - Lasse V. Karlsen
Visual Studio 2010会用警告标记这样的内容。显然,微软认为2008年不这样做是一个错误。 - Dan Is Fiddling By Firelight
不需要使用 &gt;,这是格式良好的 XML:<see cref="Expression&lt;Func&lt;T, bool>>"/> - Max Toro

1

我现在遇到这个问题了,因为我有一个返回 List<List<byte>> 的函数。是的,它很丑,但不是我写的。标准的免责声明,我知道。

无论如何,在使用 R# Ultimate 2017.1 的 VS 2017 中,这个文档注释...

<returns><see cref="List{List{Byte}}" /> of split frames</returns>

...给我一个语法错误。然而,这个...

<returns><see><cref>List{List{byte}}</cref></see> of split frames</returns>

...不会。 有趣

还是丑陋的吗?是的。

丑陋的一样吗?我认为它比我自己使用&lt;&gt;要好看一些....


0

我尝试了Stack Overflow上的所有方法,以获得在多种情况下都能正常工作的结果。以下是适用于我的解决方案。(这对其他人来说可能是主观的。)

  1. 生成可点击的链接。
  2. 悬停在标识符上时可以正常工作。
  3. 正确生成.xml文件。
  4. 在Intellisense中不会产生任何错误。
  5. 适用于可空泛型类型参数。
  6. 在Resharper和其内置的XML Doc窗口(Resharper->编辑->显示快速文档)中正常工作。
  7. 在Atomineer Pro Documentaion Visual Studio扩展的XAM Doc预览中正常工作。
  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!;

0

我来使用这个:

<see cref=""EqualityComparer{T}.Default"">EqualityComparer&lt;<typeparamref name=""TSource""/>&gt;.Default</see>

应用于您在此处的操作,结果如下:

<see cref="System.Linq.Expressions.Expression{TDelegate}">Expression&lt;Func&lt;<typeparamref name="TSource"/>, Boolean&gt;&gt;.</see>

这里是 IntelliSense 弹出窗口的图片:

Render of the comment in VS2019


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接