簡體   English   中英

從實現 class 的接口繼承注釋?

[英]Inheriting comments from an interface in an implementing class?

假設我有這個界面

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

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

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

而這個 class

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

有沒有什么辦法,或者有什么工具可以讓我自動把每個成員的評論放到一個base class或者接口里面?

因為我討厭為每個派生子類重寫相同的注釋!

您始終可以使用<inheritdoc />標簽:

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

使用cref屬性,您甚至可以在完全不同的類或命名空間中引用完全不同的成員!

public class Foo
{
    /// <inheritdoc cref="System.String.IndexOf" />
    public void Bar() { ... } // this method will now have the documentation of System.String.IndexOf
}

如果需要繼承,請使用/// <inheritdoc/> 避免使用 GhostDoc 或類似的東西。

我同意評論沒有被繼承是很煩人的。 如果有人有時間(我希望我有),這將是一個相當簡單的插件來創建。

也就是說,在我們的代碼庫中,我們只在接口上放置了 XML 注釋,並向類添加了額外的實現注釋。 這對我們有用,因為我們的類是私有/內部的,只有接口是公共的。 任何時候我們通過接口使用對象時,我們都會在智能中顯示完整的注釋。

GhostDoc 是一個良好的開端,並使編寫注釋的過程變得更容易。 當您添加/刪除參數、重新運行 GhostDoc 並更新描述時,保持注釋是最新的特別有用。

GhostDoc正是這樣做的。 對於未繼承的方法,它會嘗試根據名稱創建描述。

FlingThing()變成了"Flings the Thing" FlingThing() "Flings the Thing"

Java 有這個,我一直在使用它。 做就是了:

/**
 * {@inheritDoc}
 */

Javadoc 工具可以解決這個問題。

C# 有類似的標記:

<inheritDoc/>

你可以在這里閱讀更多:

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

我會說直接使用

/// <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);

另一種方法是使用<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() { ... }
}

更新:

我現在更喜歡使用 ReSharper 現在支持的/// <inheritdoc/>

Resharper 可以選擇從基類或接口復制注釋。

我最終創建了一個工具來對 XML 文檔文件進行后處理,以添加對替換 XML 文檔文件本身中的<inheritdoc/>標記的支持。 可在www.inheritdoc.io 獲得(提供免費版本)。

嗯,有一種本機解決方案,我為 .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配置,可以在include標簽的file屬性中將Release換成Debug

要找到正確的member name來引用,只需打開生成的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();

結束問題:
此功能已在 VS2019 v16.4 中添加。

https://developercommunity.visualstudio.com/t/608809#T-N875117

它適用於接口和抽象 class 可覆蓋成員

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM