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!
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"
Vous pouvez toujours utiliser <inheritdoc />
tag.
public class Foo : IFoo
{
/// <inheritdoc />
public void Foo() { ... }
/// <inheritdoc />
public void Bar() { ... }
/// <inheritdoc />
public void Snafu() { ... }
}
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.
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
Resharper a une option pour copier les commentaires de la classe ou de l'interface de base.
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);
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.
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).
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();