web-dev-qa-db-fra.com

Héritage des commentaires pour C # (en fait n'importe quel langage)

Supposons que j'ai cette interface

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

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

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

Et cette classe

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

Existe-t-il un moyen ou existe-t-il un outil qui peut me permettre de mettre automatiquement les commentaires de chaque membre dans une classe ou une interface de base?

Parce que je déteste réécrire les mêmes commentaires pour chaque sous-classe dérivée!

77
jumpinjackie

GhostDoc fait exactement cela. Pour les méthodes qui ne sont pas héritées, il essaie de créer une description à partir du nom.

FlingThing() devient "Flings the Thing"

18
James Curran

Vous pouvez toujours utiliser <inheritdoc /> tag.

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

Utilisation /// <inheritdoc/> si vous voulez l'héritage. Évitez GhostDoc ou quelque chose comme ça.

Je suis d'accord qu'il est ennuyeux que les commentaires ne soient pas hérités. Ce serait un complément assez simple à créer si quelqu'un avait le temps (j'aurais aimé le faire).

Cela dit, dans notre base de code, nous mettons des commentaires XML uniquement sur les interfaces et ajoutons des commentaires d'implémentation supplémentaires à la classe. Cela fonctionne pour nous car nos classes sont privées/internes et seule l'interface est publique. Chaque fois que nous utilisons les objets via les interfaces, nous avons des commentaires complets affichés dans l'intelligence.

GhostDoc est un bon début et a facilité le processus d'écriture de commentaires. Il est particulièrement utile de garder les commentaires à jour lorsque vous ajoutez/supprimez des paramètres, réexécutez GhostDoc et il mettra à jour la description.

16
Dennis

Java a cela, et je l'utilise tout le temps. Faites juste:

/**
 * {@inheritDoc}
 */

Et l'outil Javadoc le comprend.

C # a un marqueur similaire:

<inheritDoc/>

Vous pouvez lire plus ici:

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

14
JeffHeaton

Resharper a une option pour copier les commentaires de la classe ou de l'interface de base.

8
svick

Je dirais d'utiliser directement le

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

Et

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

Vous devez mettre ces commentaires juste sur la ligne précédente de votre classe/méthode

Cela obtiendra les informations de vos commentaires par exemple à partir d'une interface que vous avez documentée comme:

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

Une autre façon consiste à utiliser le <see /> Balise de documentation XML. C'est un effort supplémentaire, mais fonctionne hors de la boîte ...

Voici quelques exemples:

/// <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() { ... }
}

Mise à jour:

Je préfère maintenant utiliser /// <inheritdoc/> qui est désormais pris en charge par ReSharper.

5
Mathias Rotter

J'ai fini par créer un outil pour post-traiter les fichiers de documentation XML afin d'ajouter la prise en charge du remplacement du <inheritdoc/> tag dans les fichiers de documentation XML eux-mêmes. Disponible sur www.inheritdoc.io (version gratuite disponible).

1
K Johnson

Eh bien, il y a une sorte de solution native que j'ai trouvée pour .NET Core 2.2

L'idée est d'utiliser <include> tag.

Vous pouvez ajouter <GenerateDocumentationFile>true</GenerateDocumentationFile> votre .csproj un fichier.

Vous pourriez avoir une interface:

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

Et quelque chose qui en hérite:

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.");
    }
}

Ok, c'est un peu effrayant, mais cela ajoute les éléments attendus au YourNamespace.xml.

Si vous créez la configuration Debug, vous pouvez échanger Release contre Debug dans l'attribut file de la balise include.

Pour trouver un member correct name pour référencer, il suffit d'ouvrir le Documentation.xml fichier.

Je suppose également que cette approche nécessite la création d'un projet ou d'une solution au moins deux fois (la première fois pour créer un fichier XML initial et la deuxième fois pour copier des éléments de celui-ci vers lui-même).

Le bon côté est que Visual Studio valide les éléments copiés, il est donc beaucoup plus facile de synchroniser la documentation et le code avec l'interface/la classe de base, etc. (par exemple, les noms des arguments, les noms des paramètres de type, etc.).

À mon projet, je me suis retrouvé avec les deux <inheritdoc/> (pour DocFX) et <include/> (Pour la publication de packages NuGet et pour la validation dans 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();
0
Konard