Kommentar Vererbung für C # (eigentlich jede Sprache)

93

Angenommen, ich habe diese Schnittstelle

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

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

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

Und diese Klasse

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

Gibt es eine Möglichkeit oder gibt es ein Tool, mit dem ich die Kommentare jedes Mitglieds in einer Basisklasse oder Schnittstelle automatisch einfügen kann?

Weil ich es hasse, die gleichen Kommentare für jede abgeleitete Unterklasse neu zu schreiben!

Jumpinjackie
quelle
13
Ich hasse es nicht nur, es ist auch schwierig, sie synchron zu halten.
Olivier Jacot-Descombes

Antworten:

17

GhostDoc macht genau das. Bei Methoden, die nicht vererbt werden, wird versucht, aus dem Namen eine Beschreibung zu erstellen.

FlingThing() wird "Flings the Thing"

James Curran
quelle
2
GhostDoc ist großartig, eines der Dinge, von denen ich nicht wusste, dass ich sie brauchte, aber jetzt nicht verzichten kann: o)
NikolaiDante
177
Automatisch generierte Dokumente scheinen mir eine sehr schlechte Idee zu sein. Sie fügen keine nützlichen Informationen hinzu, sondern sprengen den Code nur unnötig. Wenn ein Tool anhand seines Namens verstehen kann, was eine Methode tut, kann eine Person auch verstehen, und es wird kein Dokument benötigt.
Lensflare
8
@Lensflare Das ist so wahr. Ich musste einmal ein Framework verwenden, das nur solche generierten Kommentare hatte, die der Methode / Klasse KEINE Informationen hinzufügten. Anstelle von "Diese Methode macht dies und das" waren die Kommentare wie "Dies ist Methode XY der Klasse Z". xD Außerdem konnten Sie den Code nicht durchsuchen, sodass es sich um Versuch und Irrtum handelte. Nie wieder! :-)
itmuckel
15
@Lensflare Während ich 100% mit Ihnen einverstanden, soweit auf dem AGDS unter Berufung wie , ich möchte darauf hinweisen , dass AGDS nicht verwendet werden soll als „do it all“ magischen Tasten so. Stattdessen sollen sie als Vorlagengeneratoren verwendet werden, um die Anzahl der sich wiederholenden Dokumentationen zu reduzieren, die Sie selbst schreiben müssen, damit Sie sich auf die wichtigen Dinge konzentrieren können. --- Zum Beispiel kann es die Erzeugung <summary>, <param>, <returns>, <throws>, etc...Abschnitte für Sie. Viele Male mit ausreichend guten Ergebnissen; In anderen Fällen müssen Korrekturen oder Erweiterungen vorgenommen werden, der Gesamtaufwand wird jedoch reduziert.
XenoRo
4
Leute, die Dokumentation ist nicht für Entwickler, sondern für Architekten, daher sind alle Themen abgedeckt: "Hey, können wir die Codedokumentation Ihres Projekts lesen? Sicher, hier ist sie."
Trident D'Gao
151

Sie können immer <inheritdoc />Tag verwenden.

public class Foo : IFoo
{
    /// <inheritdoc />
    public void Foo() { ... }
    /// <inheritdoc />
    public void Bar() { ... }
    /// <inheritdoc />
    public void Snafu() { ... }
}
Vadim
quelle
7
Ich wusste nicht, dass <inheritdoc /> überhaupt existiert ... Aber soweit ich sehen kann, wird der Kommentar für diese Methode nicht mit Intellisense angezeigt.
Gerleim
12
@gerleim Schauen Sie sich Jeff Heatons Antwort von einem Jahr zuvor und den Kommentar darunter an. Sandcastle hat <inheritdoc />, nicht C #.
Rbwhitaker
4
Ich sehe Kommentare von der Schnittstelle in Intellisense mit inheritdoc und auch, wenn es überhaupt kein Code-Dokument für die abgeleitete Klasse gibt. Aber das könnte daran liegen, dass ich einen Nachschärfer habe.
Tim Abell
9
Resharper 2017.2 hat die Unterstützung für inheritdoc jetbrains.com/resharper/whatsnew
Dav Evans
3
Visual Studio Enterprise 2017 (Version 15.9.3) zeigt für mich keine geerbten Kommentare an.
Herzbube
26

Verwenden /// <inheritdoc/>Sie diese Option, wenn Sie eine Vererbung wünschen. Vermeiden Sie GhostDoc oder ähnliches.

Ich bin damit einverstanden, dass es ärgerlich ist, dass Kommentare nicht vererbt werden. Es wäre ein ziemlich einfaches Add-In zu erstellen, wenn jemand die Zeit hätte (ich wünschte, ich hätte es getan).

In unserer Codebasis fügen wir jedoch nur XML-Kommentare zu den Schnittstellen hinzu und fügen der Klasse zusätzliche Implementierungskommentare hinzu. Dies funktioniert für uns, da unsere Klassen privat / intern sind und nur die Schnittstelle öffentlich ist. Jedes Mal, wenn wir die Objekte über die Schnittstellen verwenden, werden vollständige Kommentare in Intelligenz angezeigt.

GhostDoc ist ein guter Anfang und hat das Schreiben von Kommentaren erleichtert. Es ist besonders nützlich, die Kommentare auf dem neuesten Stand zu halten, wenn Sie Parameter hinzufügen / entfernen, GhostDoc erneut ausführen und die Beschreibung aktualisieren.

Dennis
quelle
Ich bin verwirrt - Sie sagten, vermeiden Sie GhostDoc, aber am Ende haben Sie anscheinend GhostDoc unterstützt, um die Dinge einfacher zu machen. Können Sie klarstellen, was Sie meinen?
Mike Marynowski
Danke @MikeMarynowski. Das ist ein alter Rat. Ich glaube, ich wollte damals sagen, dass GhostDoc, wie jeder andere Generator, Kommentare hinzufügen wird, aber mit fast nutzlosen Details, z <param name="origin">The origin.</param>. Weitere Beispiele finden Sie unter Ghostdoc, das die verdammtesten Dinge sagt . Visual Studio verfügt jetzt über viel bessere Flusen und Generatoren für xmldocs, damit Sie wissen, wenn Parameter + Dokumente nicht ausgerichtet sind, sodass GhostDoc (oder andere Tools) nicht mehr benötigt werden.
Dennis
15

Java hat das und ich benutze es die ganze Zeit. Mach einfach:

/**
 * {@inheritDoc}
 */

Und das Javadoc-Tool findet es heraus.

C # hat einen ähnlichen Marker:

<inheritDoc/>

Hier können Sie mehr lesen:

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

JeffHeaton
quelle
37
C # hat den <inheritdoc/>Marker nicht: Sandcastle hat ihn. shfb.codeplex.com
Eric Dand
8
Es gibt eine Benutzer-Sprachfunktionsanforderung zum Hinzufügen von <inheritdoc /> zu C #. Stimmen Sie es unter visualstudio.uservoice.com/forums/121579-visual-studio/… ab
tödlicher Hund
1
Weder C # noch Java (oder eine andere Programmiersprache) haben eines der "XML doc" -Elemente. Dies sind Kommentare . Die Compiler wissen nichts über sie. Sie werden alle strikt von Dokumentationsgeneratoren von Drittanbietern verwendet, egal ob es sich um Javadoc oder Sandburg oder was auch immer handelt.
James Curran
4
Wenn Java oder C # angegeben wird, bedeutet dies normalerweise die Community der zugehörigen Tools. Weder Java noch C # haben im wahrsten Sinne des Wortes viel Können. Es wäre ein akademisches Argument zu behaupten, dass Java oder C # nicht in der Lage sind, eine Verbindung zu einer Datenbank herzustellen, da die Laufzeitbibliothek dies tut.
JeffHeaton
2
Visual Studio Version 16.4.0 und höher bieten Intellisense für <inheritDoc />! docs.microsoft.com/en-us/visualstudio/releases/2019/…
ashbygeek
10

Ich würde sagen, die direkt zu verwenden

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

Und

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

Sie müssen diese Kommentare nur in die vorherige Zeile Ihrer Klasse / Methode einfügen

Dadurch erhalten Sie die Informationen Ihrer Kommentare beispielsweise von einer Schnittstelle, die Sie wie folgt dokumentiert haben:

    /// <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);
Gatsby
quelle
Danke für den Rat! Dieser Ansatz ist expliziter und löst das Problem der Beschreibung der Vererbungsklasse von der Objektklasse (auch bei der Implementierung der Schnittstelle).
Denis Babarykin
8

Resharper bietet die Möglichkeit, die Kommentare aus der Basisklasse oder der Schnittstelle zu kopieren.

svick
quelle
1
Oh? Wie? Ich verwende ReSharper und habe diese Option beim Implementieren oder Erben einer Schnittstelle nie gesehen ... Wo ist sie und wie verwenden Sie diese Option?
Jazimov
2
@Jazimov Wenn Sie Alt + Enter die Override-Methode eingeben, gibt es eine Option zum "Kopieren der Dokumentation von der Basis".
Svick
8

Eine andere Möglichkeit ist die Verwendung des <see />XML-Dokumentations-Tags. Dies ist ein zusätzlicher Aufwand, funktioniert aber sofort ...

Hier sind einige Beispiele:

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

Aktualisieren:

Ich bevorzuge jetzt die Verwendung, /// <inheritdoc/>die jetzt von ReSharper unterstützt wird.

Mathias Rotter
quelle
1

Am Ende habe ich ein Tool zum Nachbearbeiten der XML-Dokumentationsdateien erstellt, um Unterstützung für das Ersetzen des <inheritdoc/>Tags in den XML-Dokumentationsdateien selbst hinzuzufügen . Verfügbar unter www.inheritdoc.io (kostenlose Version verfügbar).

K Johnson
quelle
0

Nun, es gibt eine Art native Lösung, die ich für .NET Core 2.2 gefunden habe

Die Idee ist, <include>Tag zu verwenden .

Sie können hinzufügen <GenerateDocumentationFile>true</GenerateDocumentationFile>Ihre .csprojDatei.

Möglicherweise haben Sie eine Schnittstelle:

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

Und etwas, das davon erbt:

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, es ist ein bisschen beängstigend, aber es fügt die erwarteten Elemente hinzu YourNamespace.xml.

Wenn Sie bauen DebugKonfiguration können Sie tauschen Releasefür Debugim fileAttribut - includeTag.

Um eine korrekte zu finden member‚s namenur offen erzeugt Referenz - Documentation.xmlDatei.

Ich gehe auch davon aus, dass für diesen Ansatz ein Projekt oder eine Lösung mindestens zweimal erstellt werden muss (zum ersten Mal, um eine erste XML-Datei zu erstellen, und zum zweiten Mal, um Elemente daraus in sich selbst zu kopieren).

Die gute Seite ist, dass Visual Studio kopierte Elemente validiert, sodass es viel einfacher ist, Dokumentation und Code mit der Schnittstelle / Basisklasse usw. synchron zu halten (z. B. Namen von Argumenten, Namen von Typparametern usw.).

Bei meinem Projekt habe ich sowohl <inheritdoc/>(für DocFX) als auch <include/>(für die Veröffentlichung von NuGet-Paketen und für die Validierung in Visual Studio) Folgendes erreicht :

        /// <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();
Konard
quelle