用相同的 XML 注释记录重载方法

Posted

技术标签:

【中文标题】用相同的 XML 注释记录重载方法【英文标题】:Documenting overloaded methods with the same XML comments 【发布时间】:2011-04-09 17:28:26 【问题描述】:

假设我有这个构造函数:

/// <summary>
/// Example comment.
/// </summary>
public SftpConnection(string host, string username, 
    string password, int port) ...

有这些重载:

public SftpConnection(string host, string username, string password) 
    : this(host, username, password, 22)  

public SftpConnection(string host, string username, int port) 
    : this(host, username, "", port)  

public SftpConnection(string host, string username) 
    : this(host, username, "", 22)  

实际上,XML 注释非常大,有paramexampleexception 等元素。

有没有办法为重载添加一个特殊的 XML 注释单行,这样它们使用完全相同的 cmets,这样我就不需要复制粘贴整个巨大的原始 cmets?

我在想类似:&lt;use cref="SftpConnection(string,string,string,int)" /&gt; 这当然行不通。

我知道include 元素,但我得到的印象是它从 XML 文件中读取 cmets,这是我不想要的 - 我希望注释在代码中仍然可见,但是 只有一次

谢谢:-)

【问题讨论】:

这个问题已经很老了——对于新来的人来说,谷歌搜索“inheritdoc”应该希望你能找到你所寻求的答案。 (这取决于您的选择和要求。) @AnorZaken 您应该发表您的评论作为答案,它实际上非常有用。 @konrad.kruczynski 没有回答这个问题。它继承了整个 xmldoc 注释块,而不是来自重载方法(或构造函数)的特定参数 cmets。这个问题仍然很有效,因为除了下面 Timwi 建议的解决方法之外,我无法找到令人满意的答案。 @AnorZaken 嗯,是的。 InheritDoc 正是我正在寻找的答案。是的,它确实继承了重载方法的特定参数。是的,您可以在其后添加单个参数以获得唯一参数。不再复制/粘贴 cmets!谢谢! 【参考方案1】:

你真的不能这样做。我也觉得很烦。

但是,您可以通过使用默认参数值而不是大量重载来缓解此问题。而不是:

public SftpConnection(string host, string username, string password, int port)
public SftpConnection(string host, string username, string password)
public SftpConnection(string host, string username, int port)
public SftpConnection(string host, string username)

你可以只有一个:

public SftpConnection(string host, string username, string password = "",
                      int port = 22)

这有很多好处:

只需要一个 XML 注释。我回答的重点。 ☺

Visual Studio 的用户可以立即看到 port 的默认值为 22。对于重载,这并不明显;您必须在文档中特别提及。

您通过鼓励使用命名参数间接鼓励客户端代码变得更具可读性(例如,port: 2222 而不是仅仅2222,这不太清楚)。

最重要的是,使用默认值不会删除在需要时仍然有多个重载的能力。您希望使用默认值进行重载的典型示例可能类似于...

ReadFrom(string filename, ReaderOptions options = null)
ReadFrom(Stream stream, ReaderOptions options = null)
ReadFrom(byte[] rawData, ReaderOptions options = null)

在这些情况下,我认为 XML cmets 实际上应该是不同的。

【讨论】:

你说得对。我已按照您的建议更改了代码。尽管如此,这将在未来困扰我!并且必须在其他情况下需要此功能。 当然。就像我说的,我也觉得这很烦人。默认值只是缓解问题,而不是解决它... @Tergiver:当然。我通常认为没有必要说,因为人们不得不使用过时的东西并不常见。 @Timwi:实际上,我发现人们使用旧版本的 .NET 很常见,出于某种奇怪的原因,公司有时很难转向新技术。例如,我仍在使用 3.5 进行工作。 @JoshuaGruber:我认为文章中唯一相关的指南是最后一个,他们警告您上述技术不符合 CLS。所以我会说如果你坚持使用 VB.NET / C# 很好,但如果你需要将你的函数公开给其他语言,那就更少了。【参考方案2】:

InheritDoc 非常适合过载(至少在 VS 2019 中)。您也可以覆盖它的任何部分。官方文档说:

从基类、接口和类似方法继承 XML cmets。

/// <summary>
/// Method does something
/// </summary>
/// <param name="someString">Some string</param>
public void SomeMethod(string someString)



/// <param name="someInt">Some int</param>
/// <inheritdoc cref="SomeMethod(string)"/>
public void SomeMethod(string someString, int someInt)



/// <summary>Override the summary part</summary>
/// <param name="someString">Description for someString overridden</param>
/// <param name="anotherInt">Another int</param>
/// <inheritdoc cref="SomeMethod(string, int)"/>
public void SomeMethod(string someString, int someInt, int anotherInt)



/// <typeparam name="TOtherType">Other type</typeparam>
/// <inheritdoc cref="IInterfaceTModel,TKey.SomeMethodTType(TType)"/>
public void SomeMethod<TType, TOtherType>(TType first, TOtherType second)


【讨论】:

这对我不起作用。我在我的接口方法上试过了。重载没有显示摘要。 您是否指定了cref 属性?没有它就行不通。 它适用于普通方法,但不适用于具有泛型的方法 更新了我的答案以显示使用泛型时的语法。 遗憾地可以确认这不适用于 VS 2017(可能更早)。【参考方案3】:

一个半解决方案是&lt;overloads&gt;&lt;/overloads&gt; 标签。虽然它不能解决 &lt;summary/&gt; 的问题,但它确实提供了显示所有重载作为一个组列出的任何位置的文档,包括 IntelliSense 和 SandCastle。

【讨论】:

【参考方案4】:

这是你想要的吗?

/// <seealso cref="SftpConnection(string,string,string,int)"</seealso>

【讨论】:

那行不通,但我会研究 seealso 元素,TY。 好的,我似乎无法让seealso任何事情。远射,但这可能与 c# 或 .net 的版本有关吗? 我认为它的目的是使用 doxygen 和其他文档工具创建丰富的 html 文档...不过看看它的作用...您使用的是什么版本的 VS(或者您使用的是 Mono )? VS 2010 - 我认为你必须使用完全限定的名称,所以你的例子可能不起作用。 在查看了 Visual Studio 的文档并尝试了几种解决方法后,我决定 &lt;seealso&gt;&lt;/seealso&gt; 仅供参考。【参考方案5】:

我来自谷歌,我想根据上面的讨论分享我的解决方案。

假设你有两个方法,其中一个是重载:

public void MethodA(string paramA);
public void MethodA(string paramA, string paramB);

为了将它们映射到 XML 文件文档,您需要使用以下注释:

/// <include file='Docs/MyXMLFile.xml' path='docs/members/MethodA/*'/>
public void MethodA(string paramA);

/// <include file='Docs/MyXMLFile.xml' path='docs/members/MethodA/*'/>
public void MethodA(string paramA, string paramB);

在您的 XML 文件中,您需要使用 @Kache 告知的 &lt;overloads&gt; 标签,唯一需要注意的是需要尊重的层次结构,所以最终的解决方案就像这个:

在 MyXMLFile.xml 中

<overloads>
<MethodA>
      <summary>
       My MethodA...  
      </summary>
      <param name="paramA">
        My ParamA....
      </param>
</MethodA>
<MethodA>
      <summary>
       My MethodA...  
      </summary>
      <param name="paramA">
        My ParamA....
      </param>
      <param name="paramB">
        My ParamB....
      </param>
</MethodA>
</overloads>

【讨论】:

以上是关于用相同的 XML 注释记录重载方法的主要内容,如果未能解决你的问题,请参考以下文章

跨重载共享xml文档

Java 方法重载

Java 方法重载和多态

C++的=重载问题,怎样为两个有相同成员的类赋值

JAVA基础-----方法重载

当两个重载具有相同的签名时调用构造函数重载