在C#中同步接口和实现注释的方法


98

是否有自动的方法在界面及其实现之间同步注释?我目前正在记录它们,并且不想手动保持它们同步。

更新:

考虑以下代码:

interface IFoo{
    /// <summary>
    /// Commenting DoThis method
    /// </summary>
    void DoThis();
}
class Foo : IFoo {
    public void DoThis();
}

当我创建这样的类时:

IFoo foo=new Foo();
foo.DoThis();//comments are shown in intellisense

这里的注释未显示:

Foo foo=new Foo();
foo.DoThis();//comments are not shown in intellisense

<inheritDoc/>标签将完美地在Sand Castle中生成文档,但是在智能感知工具提示中不起作用。

请分享您的想法。

谢谢。



如果有接口文档可用,我如何使Atomineer Pro生成<inheritDoc />文档标签以供实施?
hellboy 2014年

3
你是对的<inheritdoc/>,在Visual Studio中已被打破。请通过visualstudio.uservoice.com/forums/121579-visual-studio/…
Panic

Answers:


62

您可以使用Microsoft Sandcastle(或NDoc)inheritdoc标记轻松地完成此操作。规范未正式支持它,但是自定义标签是完全可以接受的,实际上,Microsoft在创建Sandcastle时选择了从NDoc复制此标签(以及一个或两个其他标签)。

/// <inheritdoc/>
/// <remarks>
/// You can still specify all the normal XML tags here, and they will
/// overwrite inherited ones accordingly.
/// </remarks>
public void MethodImplementingInterfaceMethod(string foo, int bar)
{
    //
}

是Sandcastle帮助文件生成器GUI的帮助页面,其中完整描述了它的用法。

(当然,正如您的问题所提到的,这并不是专门的“同步”,但这似乎正是您要寻找的。)

需要注意的是,对我来说,这听起来似乎是个很公平的主意,尽管我发现有些人认为您应该始终在派生类和实现类中重新指定注释。(我实际上是在记录我的一个库时亲自做的,而且我什么都没看到。)几乎总是没有理由使注释完全不同,所以为什么不继承并以一种简单的方式呢?

编辑:关于您的更新,沙堡(Sandcastle)也可以为您处理。Sandcastle可以输出用于输入的实际XML文件的修改后的版本,这意味着您可以将此修改后的版本与库DLL一起分发,而不是由Visual Studio直接构建的版本分发,这意味着您具有intellisense以及文档文件(CHM,等等)。


嘿,太好了!我喜欢沙堡!
Tor Haugen,2009年

编辑帖子以回答更新的问题。
诺多林

2
可以在课堂上完成吗?这样我就不必在每个方法前都加上/// <inheritdoc />。
安东尼·斯科特

1
我注意到的一件事是,<inheritdoc/> 它不会继承该<param>标记的文档。
stephen,2014年

1
投票支持此用户语音功能,将<inheritdoc />正式添加到C#规范中,并与VS intellisense visualstudio.uservoice.com/forums/121579-visual-studio/一起使用
deadlydog

14

如果您还没有使用它,我强烈建议您使用一个免费的Visual Studio插件GhostDoc。它简化了文档编制过程。看看我的评论对某个相关问题的。

尽管GhostDoc不会自动进行同步,但可以在以下情况下为您提供帮助:

您有一个记录的接口方法。在一个类中实现此接口,按GhostDoc快捷键,Ctrl-Shift-D该接口的XML注释将添加到实现的方法中。

转到选项->键盘设置,然后为GhostDoc.AddIn.RebuildDocumentation(我使用Ctrl-Shift-Alt-D)分配一个键。 替代文字

现在,如果您更改接口上的XML注释,只需在已实现的方法上按此快捷键,即可更新文档。不幸的是,反之亦然。


GhostDoc的最新版本(5.3.16270)也可以创建继承的文档。我只是在接口实现中尝试过。很好的好处是,它还会添加异常以及抛出异常的消息:-)
Christoph

6

我通常会这样写评论:

/// <summary>
/// Implements <see cref="IMyInterface.Foo(string, int)"/>
/// </summary>
/// <returns></returns>

这些方法仅由接口使用,因此在编码时此注释甚至都不会显示在工具提示中。

编辑:

如果要在直接调用类而不使用接口时看到文档,则需要编写两次或使用类似GhostDoc的工具。


4

试试GhostDoc!这个对我有用 :-)

编辑:现在,我已经意识到Sandcastle对的支持<inheritdoc/>,我赞同Noldorin的帖子。这是一个更好的解决方案。不过,我还是一般性地推荐GhostDoc。


6
我个人不喜欢GhostDoc。它生成实际上没有文档的文档。这掩盖了一个事实,那就是没有文件记录。只是我个人的观点,我并不是说这总体上是不好的。
Stefan Steinegger,2009年

1
同意Stefan的意见,认为GhostDoc并不完美,但是它确实会自动引入这样的“继承”评论,因此它是该问题的很好答案。
史蒂夫

Stefan,我不同意-相反,因为GhostDoc仅反映您已经“放入”成员名称的文档(通过从名称中构建散文),因此它仅生成已经存在文档的文档(隐式)。这样,它什么都不会“产生”,但是所产生的散文是可以增加实际价值的绝佳起点。实际的文档仍然需要一些工作。
Tor Haugen,2009年

2

我有一个更好的答案:FiXml,我是它的作者之一

克隆固然是行之有效的方法,但是它有很多缺点,例如:

  • 更改原始注释(在开发过程中经常发生)时,其副本不会更改。
  • 您正在产生大量重复项。如果您使用任何源代码分析工具(例如Team City中的Duplicate Finder),它将主要找到您的注释。

如前所述,Sandcastle中<inheritdoc>tag,但是与FiXml相比,它几乎没有缺点:

  • Sandcastle会生成已编译的HTML帮助文件-通常它不会修改 .xml包含提取的XML注释的文件(最后,在编译过程中无法“即时”完成此操作)。
  • 沙堡的实现功能不那么强大。例如,否 <see ... copy="true" />

有关更多详细信息,请参见Sandcastle的<inheritdoc>说明

FiXml的简短说明:它是C#\ Visual Basic .Net生成的XML文档的后处理器。它是作为MSBuild任务实现的,因此很容易将其集成到任何项目中。它解决了一些与使用这些语言编写XML文档有关的烦人的案例:

  • 不支持从基类或接口继承文档。即,任何重写的成员的文档都应从头开始编写,尽管通常最好至少继承其中的一部分。
  • 不支持插入常用文档模板,例如“此类型为单例-使用其<see cref="Instance" />属性获取它的唯一实例。”,甚至“初始化一个新的<CurrentType>类实例” 。

为了解决上述问题,提供了以下其他XML标签:

  • <inheritdoc />, <inherited /> 标签
  • <see cref="..." copy="..." /><see/>标签中的属性。

这是其网页下载页面



1

我构建了一个库来对XML文档文件进行后处理,以添加对<inheritdoc />标记的支持。

尽管它对源代码中的Intellisense没有帮助,但它确实允许将修改后的XML文档文件包含在NuGet包中,因此可以在引用的NuGet包中与Intellisense一起使用。

有关更多信息,请访问www.inheritdoc.io(提供免费版本)。


0

不要那样做 以这种方式思考-如果两个注释始终要求相同,那么其中一个注释就不必要了。注释必须有一个原因(除了某种怪异的义务,即注释每个函数和变量),因此您需要弄清楚该独特原因是什么,并将其记录在案。


3
如果没有在测试中伪造界面,我就不会在这里使用界面。
Valentin Vasilyev,2009年

0

使用ReSharper,您可以复制它,但是我不认为它一直都在同步。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.