C#的注释继承(实际上是任何语言)


93

假设我有这个介面

public interface IFoo
{
    ///<summary>
    /// Foo method
    ///</summary>
    void Foo();

    ///<summary>
    /// Bar method
    ///</summary>
    void Bar();

    ///<summary>
    /// Situation normal
    ///</summary>
    void Snafu();
}

而这个班

public class Foo : IFoo
{
    public void Foo() { ... }
    public void Bar() { ... }
    public void Snafu() { ... }
}

有没有办法,或者有什么工具可以让我自动在基类或接口中加入每个成员的注释?

因为我讨厌为每个派生子类重写相同的注释!


13
我不仅讨厌它,而且很难保持它们同步。
Olivier Jacot-Descombes

Answers:


17

GhostDoc正是这样做的。对于未继承的方法,它将尝试根据名称创建描述。

FlingThing() 变成 "Flings the Thing"


2
GhostDoc非常棒,我不知道自己需要做的事情之一,但现在已经离不开:o)
NikolaiDante

178
自动生成的文档对我来说似乎是个坏主意。他们没有添加任何有用的信息,而只是不必要地炸毁了代码。如果工具可以从名称中了解方法的作用,那么一个人也可以理解,不需要任何文档。
Lensflare

8
@Lensflare这是真的。我曾经不得不使用仅包含生成的注释的框架,该框架未向方法/类添加任何信息。而不是使用“此方法执行此操作和那样”的注释,例如“这是类Z的方法XY”。xD同样,您也不会浏览该代码,因此它陷入了反复试验。再也不!:-)
itmuckel

15
@Lensflare虽然我100%同意你的看法,只要在AGDS依托的是,我应该指出的是,AGDS是注定不会被用作“做这一切的”神奇按钮这样。而是将它们用作模板生成器,以减少样例的数量,这是您必须自己编写的重复性文档,因此您可以专注于重要的内容。---例如,它可以生成<summary><param><returns><throws>etc...为你的部分。多次,结果都不错;其他时间需要更正或扩展,但仍会减少整体工作量。
XenoRo

4
人们的文档不是给开发人员的,而是给建筑师的,所以他们的屁股都被覆盖了:“嘿,我们可以阅读您项目的代码文档吗?当然可以。”
Trident D'Gao

151

您可以随时使用<inheritdoc />标签。

public class Foo : IFoo
{
    /// <inheritdoc />
    public void Foo() { ... }
    /// <inheritdoc />
    public void Bar() { ... }
    /// <inheritdoc />
    public void Snafu() { ... }
}

7
我什至不知道<inheritdoc />是否存在...但是据我所知,这种方法的注释并没有显示在intellisense上。
gerleim 2014年

12
@gerleim查看一年前杰夫·希顿的回答,以及下面的评论。Sandcastle具有<inheritdoc />,而不是C#。
rbwhitaker 2015年

4
我在带有intellisense的Inheriteddoc中看到了来自接口的注释,并且在派生类上是否根本没有代码文档。但这可能是因为我有剃须刀。
蒂姆·阿贝尔

9
Resharper 2017.2改进了对herentdocdoc jetbrains.com/resharper/whatsnew的
Dav Evans

3
Visual Studio Enterprise 2017(版本15.9.3)不会为我显示继承的注释。
herzbube

26

/// <inheritdoc/>如果要继承,请使用。避免使用GhostDoc或类似的东西。

我同意注释不被继承是令人讨厌的。如果有人有时间(我希望我有时间),这将是一个非常简单的外接程序。

就是说,在我们的代码库中,我们仅将XML注释放在接口上,并向该类添加额外的实现注释。这对我们有用,因为我们的课程是私有/内部的,并且只有接口是公共的。每当我们通过界面使用对象时,我们都会以智能方式显示完整的注释。

GhostDoc是一个良好的开端,它使编写注释的过程更加容易。在添加/删除参数,重新运行GhostDoc并更新描述时,使注释保持最新尤其有用。


我很困惑-您说避免使用GhostDoc,但是最后您似乎支持GhostDoc来简化事情。您能说明您的意思吗?
Mike Marynowski

谢谢@MikeMarynowski。这是建议。我想当时我想说的是,GhostDoc与其他任何生成器一样,将添加注释,但包含几乎无用的细节,例如<param name="origin">The origin.</param>。有关更多示例,请参见ghostdoc说的最该死的事情。Visual Studio现在具有更好的linting和xmldocs生成器,可以在参数+文档不对齐时通知您,因此不再需要GhostDoc(或其他工具)。
丹尼斯

15

Java有此功能,我一直都在使用它。做就是了:

/**
 * {@inheritDoc}
 */

Javadoc工具可以解决这个问题。

C#具有类似的标记:

<inheritDoc/>

你可以在这里阅读更多:

http://www.ewoodruff.us/shfbdocs/html/79897974-ffc9-4b84-91a5-e50c66a0221d.htm


37
C#没有<inheritdoc/>标记:Sandcastle有标记。shfb.codeplex.com
Eric Dand

8
有一个用户语音功能请求,用于将<inheritdoc />添加到C#。请在visualstudio.uservoice.com/forums/121579-visual-studio/
deadlydog

1
C#和Java(也没有其他任何编程语言)都没有任何“ XML doc”元素。这些是评论。编译器对此一无所知。第三方文档生成器都严格使用它们,无论是javadoc还是sandcastle或其他任何形式。
James Curran

4
当声明Java或C#时,它通常表示关联工具的社区。从字面上看,Java和C#都没有太多的功能。指出Java或C#缺乏连接数据库的能力将是一个学术论点,因为运行时库可以做到这一点。
JeffHeaton

2
Visual Studio版本16.4.0及更高版本为<inheritDoc />提供了智能感知功能!docs.microsoft.com/en-us/visualstudio/releases/2019/...
ashbygeek

10

我会说直接使用

/// <inheritdoc cref="YourClass.YourMethod"/>  --> For methods inheritance

/// <inheritdoc cref="YourClass"/>  --> For directly class inheritance

您必须将此注释放在课程/方法的前一行

例如,这将从您已记录的界面中获取评论信息:

    /// <summary>
    /// This method is awesome!
    /// </summary>
    /// <param name="awesomeParam">The awesome parameter of the month!.</param>
    /// <returns>A <see cref="AwesomeObject"/> that is also awesome...</returns>
    AwesomeObject CreateAwesome(WhateverObject awesomeParam);

谢谢你的建议!这种方法更加明确,解决了从对象类继承类描述的问题(即使在实现接口时)。
Denis Babarykin

8

Resharper可以选择从基类或接口复制注释。


1
哦?怎么样?我使用ReSharper,在实现或继承接口时从未见过该选项。它在哪里,以及如何使用该选项?
Jazimov '16

2
@Jazimov当您Alt + Enter覆盖方法时,有一个选项“从基础复制文档”。
2013年

8

另一种方法是使用<see />XML文档标签。这是一项额外的工作,但可以立即使用...

这里有些例子:

/// <summary>
/// Implementation of <see cref="IFoo"/>.
/// </summary>
public class Foo : IFoo
{
    /// <summary>
    /// See <see cref="IFoo"/>.
    /// </summary>
    public void Foo() { ... }

    /// <summary>
    /// See <see cref="IFoo.Bar"/>
    /// </summary>
    public void Bar() { ... }

    /// <summary>
    /// This implementation of <see cref="IFoo.Snafu"/> uses the a caching algorithm for performance optimization.
    /// </summary>
    public void Snafu() { ... }
}

更新:

我现在更喜欢使用/// <inheritdoc/>ReSharper支持的功能。


1

我最终创建了一个对XML文档文件进行后处理的工具,以添加对替换<inheritdoc/>XML文档文件本身中的标记的支持。可从www.inheritdoc.io获得(提供免费版本)。


0

好吧,我找到了一种针对.NET Core 2.2的本地解决方案

这个想法是使用<include>标签。

您可以添加<GenerateDocumentationFile>true</GenerateDocumentationFile>您的.csproj文件。

您可能有一个接口:

namespace YourNamespace
{
    /// <summary>
    /// Represents interface for a type.
    /// </summary>
    public interface IType
    {
        /// <summary>
        /// Executes an action in read access mode.
        /// </summary>
        void ExecuteAction();
    }
}

从中继承的东西:

using System;

namespace YourNamespace
{
    /// <summary>
    /// A type inherited from <see cref="IType"/> interface.
    /// </summary>
    public class InheritedType : IType
    {
        /// <include file='bin\Release\netstandard2.0\YourNamespace.xml' path='doc/members/member[@name="M:YourNamespace.IType.ExecuteAction()"]/*'/>
        public void ExecuteAction() => Console.WriteLine("Action is executed.");
    }
}

好的,这有点吓人,但是确实将预期的元素添加到中YourNamespace.xml

如果你建立Debug的配置,你可以换ReleaseDebugfile属性include标签。

要找到正确membername引用,只需打开生成的Documentation.xml文件即可。

我还假设这种方法要求一个项目或解决方案至少要构建两次(第一次创建一个初始XML文件,第二次将元素从其复制到自身)。

好的一面是Visual Studio会验证复制的元素,因此使文档和代码与接口/基类等保持同步(例如,参数名称,类型参数的名称等)要容易得多。

在我的项目中,我最终同时使用了<inheritdoc/>(对于DocFX)和<include/>(用于发布NuGet程序包并在Visual Studio中进行验证):

        /// <inheritdoc />
        /// <include file='bin\Release\netstandard2.0\Platform.Threading.xml' path='doc/members/member[@name="M:Platform.Threading.Synchronization.ISynchronization.ExecuteReadOperation(System.Action)"]/*'/>
        public void ExecuteReadOperation(Action action) => action();
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.