Коментар Спадщина для 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() { ... }
}

Чи є спосіб, чи є інструмент, який дозволяє мені автоматично поміщати коментарі кожного члена в базовий клас або інтерфейс?

Тому що я ненавиджу переписувати однакові коментарі для кожного похідного підкласу!


14
Я не тільки ненавиджу це, але також важко тримати їх синхронізовано.
Олів'є Жако-Декомб

Відповіді:


17

GhostDoc робить саме це. Для методів, які не успадковуються, він намагається створити опис з імені.

FlingThing() стає "Flings the Thing"


2
GhostDoc чудовий, одна з тих речей, про які я не знав, що мені потрібні, але тепер без них не обійтися: o)
NikolaiDante

180
Автоматично створені документи здаються мені дуже поганою ідеєю. Вони не додають ніякої корисної інформації, а лише підривають код без потреби. Якщо інструмент може зрозуміти, що метод робить з його назви, тоді людина також може зрозуміти, і ніякий документ не потрібен.
Lensflare

8
@Lensflare Це так правда. Одного разу мені довелося використовувати фреймворк, який мав лише такі згенеровані коментарі, які не додавали ніякої інформації до методу / класу. Замість "Цей метод робить це і те" коментарі, де на зразок "Це метод XY класу Z". xD Також ви не могли переглядати код, тому він потрапив до спроб та помилок. Ніколи знову! :-)
itmuckel

15
@Lensflare Незважаючи на те, що я на 100% погоджуюсь з вами, наскільки покладаюся на AGD, як є , я повинен зазначити, що AGD не призначені для використання як такі чарівні кнопки "зроби все". Натомість вони призначені для використання в якості генераторів шаблонів для зменшення кількості зразків, повторюваної документації, яку ви повинні написати самостійно, щоб ви могли зосередитися на важливих речах. --- Наприклад, він може генерувати <summary>, <param>, <returns>, <throws>, etc...секції для вас. Багато разів із досить хорошими результатами; інший раз потребують виправлення або розширення, але все одно зменшують загальні зусилля.
XenoRo

5
людям документація не для розробників, а для архітекторів, тому всі їх приклади покриті: "Гей, ми можемо прочитати кодову документацію вашого проекту? Звичайно, ось вона".
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

12
@gerleim Подивіться на відповідь Джеффа Хітона роком раніше та коментар під нею. Sandcastle має <nasleditdoc />, а не C #.
rbwhitaker

4
Я бачу коментарі з інтерфейсу в intellisense з nasleditdoc, а також якщо коду-документа взагалі немає у похідному класі. Але це може бути тому, що я маю resharper.
Тім Абелл

9
Resharper 2017.2 покращив підтримку для наследства jetbrains.com/resharper/whatsnew
Dav Evans

3
Visual Studio Enterprise 2017 (версія 15.9.3) для мене не відображає успадковані коментарі.
herzbube

26

Використовуйте, /// <inheritdoc/>якщо хочете успадкування. Уникайте GhostDoc або чогось подібного.

Я згоден, що дратує те, що коментарі не передаються у спадок. Це було б досить простим надбудовою для створення, якби хтось мав час (я би хотів, щоб у мене було).

Тим не менш, у нашій базі коду ми розміщуємо коментарі XML лише на інтерфейсах і додаємо додаткові коментарі до реалізації до класу. Це працює для нас, оскільки наші класи є приватними / внутрішніми, і лише інтерфейс є загальнодоступним. Кожного разу, коли ми використовуємо об'єкти через інтерфейси, ми маємо повне відображення коментарів у взаємодії.

GhostDoc - це хороший старт, який спростив процес написання коментарів. Особливо корисно постійно оновлювати коментарі, коли ви додаєте / видаляєте параметри, повторно запускаєте GhostDoc, і він оновить опис.


Я розгублений - ви сказали уникати GhostDoc, але в кінці там ви, мабуть, підтримали GhostDoc, допомагаючи полегшити ситуацію. Чи можете ви пояснити, що ви маєте на увазі?
Майк Мариновський

Дякую @MikeMarynowski. Це стара порада. Я думаю, що я хотів сказати тоді, що GhostDoc, як і будь-який інший генератор, додаватиме коментарі, але з майже марними подробицями, наприклад <param name="origin">The origin.</param>. Дивіться ghostdoc, який говорить найдивовижніші речі, щоб отримати більше прикладів. Visual Studio тепер має набагато кращі підключення та генератори для 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
Ерік Данд

8
Існує запит голосової функції користувача, щоб додати <inheritdoc /> до C #. Підніміться і проголосуйте за цим на visualstudio.uservoice.com/forums/121579-visual-studio/…
deadlydog

1
Ні C #, ні Java (ані будь-яка інша мова програмування) не мають жодного з елементів "XML doc". Це коментарі . Укладачі нічого про них не знають. Всі вони строго використовуються сторонніми генераторами документації, будь то javadoc чи пісочний замок або що завгодно.
Джеймс Курран,

4
Коли вказано Java або C #, це ЗВИЧАЙНО означає спільноту пов'язаних інструментів. Ні Java, ні C # не мають великих можливостей у прямому сенсі. Було б академічним аргументом стверджувати, що Java або C # не мають можливості підключатися до бази даних, оскільки це робить бібліотека часу виконання.
JeffHeaton

2
Visual Studio версії 16.4.0 та новіших забезпечує intellisense для <nasleditDoc />! 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);

Дякую за пораду! Цей підхід є більш явним і вирішує проблему опису класу успадкування від класу об'єкта (навіть при реалізації інтерфейсу).
Денис Бабарікін

8

Resharper має можливість копіювати коментарі з базового класу або інтерфейсу.


1
О? Як Я використовую ReSharper, і я ніколи не бачив цієї опції при реалізації або успадкуванні інтерфейсу ... Де він знаходиться і як ви використовуєте цю опцію?
Язимов

2
@Jazimov Коли ви натискаєте Alt + Введіть метод перевизначення, є опція "Копіювати документацію з бази".
svick

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конфігурацію, ви можете поміняти місцями Releaseдля Debugв fileатрибуті includeтега.

Для того, щоб знайти правильний member«S , 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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.