Sposoby synchronizacji interfejsu i komentarzy do implementacji w C # [zamknięte]


98

Czy istnieją automatyczne sposoby synchronizowania komentarzy między interfejsem a jego implementacją? Obecnie dokumentuję je obie i nie chciałbym ich synchronizować ręcznie.

AKTUALIZACJA:

Rozważ ten kod:

interface IFoo{
    /// <summary>
    /// Commenting DoThis method
    /// </summary>
    void DoThis();
}
class Foo : IFoo {
    public void DoThis();
}

Kiedy tworzę taką klasę:

IFoo foo=new Foo();
foo.DoThis();//comments are shown in intellisense

Tutaj komentarze nie są wyświetlane:

Foo foo=new Foo();
foo.DoThis();//comments are not shown in intellisense

<inheritDoc/>Tag będzie idealnie generować dokumentację w zamek z piasku, ale to nie działa w podpowiedziach IntelliSense.

Podziel się swoimi pomysłami.

Dzięki.


Czy ta funkcja została zaimplementowana? visualstudio.uservoice.com/forums/121579-visual-studio/…
hellboy

Jak sprawić, by Atomineer Pro pozwolił wygenerować tag dokumentacji <inheritDoc /> do wdrożenia, jeśli dokumentacja interfejsu jest dostępna?
hellboy,

3
Masz rację <inheritdoc/>jest uszkodzony w programie Visual Studio. Zagłosuj na raport o błędzie
Colonel Panic

Odpowiedzi:


62

Możesz to zrobić dość łatwo, używając inheritdoctagu Microsoft Sandcastle (lub NDoc) . Nie jest oficjalnie wspierany przez specyfikację, ale niestandardowe tagi są całkowicie akceptowalne i rzeczywiście Microsoft zdecydował się skopiować ten (i jeden lub dwa inne tagi) z NDoc podczas tworzenia Sandcastle.

/// <inheritdoc/>
/// <remarks>
/// You can still specify all the normal XML tags here, and they will
/// overwrite inherited ones accordingly.
/// </remarks>
public void MethodImplementingInterfaceMethod(string foo, int bar)
{
    //
}

Oto strona pomocy z GUI Sandcastle Help File Builder, która w pełni opisuje jego użycie.

(Oczywiście nie jest to konkretnie „synchronizacja”, jak wspomina Twoje pytanie, ale wydaje się, że jest to dokładnie to, czego szukasz).

Uwaga, brzmi to dla mnie jak całkowicie uczciwy pomysł, chociaż zauważyłem, że niektórzy ludzie uważają, że zawsze należy ponownie określać komentarze w klasach pochodnych i zaimplementowanych. (Zrobiłem to sam, dokumentując jedną z moich bibliotek i nie widzę żadnych problemów). Prawie zawsze nie ma powodu, aby komentarze w ogóle się różniły, więc dlaczego nie odziedziczyć i zrobić to w prosty sposób?

Edycja: Jeśli chodzi o aktualizację, Sandcastle może się tym zająć. Sandcastle może wyprowadzić zmodyfikowaną wersję rzeczywistego pliku XML, którego używa do wprowadzania danych, co oznacza, że ​​możesz rozpowszechniać tę zmodyfikowaną wersję wraz z biblioteką DLL zamiast tej utworzonej bezpośrednio przez Visual Studio, co oznacza, że ​​masz komentarze w intelisense, a także plik dokumentacji (CHM, cokolwiek).


Hej, to całkiem miłe! Lubię Sandcastle!
Tor Haugen

Post został zmodyfikowany, aby odpowiedzieć na zaktualizowane pytanie.
Noldorin

2
czy można to zrobić na poziomie klasy? aby nie musieć umieszczać /// <inheritdoc /> przed każdą metodą.
Antony Scott,

1
Zauważyłem, że <inheritdoc/> nie dziedziczy on dokumentacji <param>tagu.
stephen

1
Głosuj w górę na tę funkcję głosu użytkownika, aby oficjalnie dodać <inheritdoc /> do specyfikacji C # i współpracować z VS intellisense visualstudio.uservoice.com/forums/121579-visual-studio/ ...
deadlydog

14

Jeśli jeszcze go nie używasz, zdecydowanie polecam darmowy dodatek do Visual Studio o nazwie GhostDoc . Ułatwia proces dokumentacji. Spójrz na mój komentarz do nieco pokrewnego pytania.

Chociaż GhostDoc nie wykona synchronizacji automatycznie, może pomóc w następującym scenariuszu:

Masz udokumentowaną metodę interfejsu. Zaimplementuj ten interfejs w klasie, naciśnij klawisz skrótu GhostDoc Ctrl-Shift-D, a komentarz XML z interfejsu zostanie dodany do zaimplementowanej metody.

Przejdź do Opcje -> Ustawienia klawiatury i przypisz klawisz do GhostDoc.AddIn.RebuildDocumentation(użyłem Ctrl-Shift-Alt-D). tekst alternatywny

Teraz, jeśli zmienisz komentarz XML w interfejsie , po prostu naciśnij ten klawisz skrótu na zaimplementowanej metodzie, a dokumentacja zostanie zaktualizowana. Niestety, to nie działa odwrotnie.


Najnowsza wersja (5.3.16270) GhostDoc może również tworzyć odziedziczone dokumenty. Właśnie wypróbowałem to w moich implementacjach interfejsu. Niezły bonus, dodaje też wyjątki z przesłaniem wrzuconego wyjątku :-)
Christoph

6

Zwykle piszę takie komentarze:

/// <summary>
/// Implements <see cref="IMyInterface.Foo(string, int)"/>
/// </summary>
/// <returns></returns>

Metody są używane tylko przez interfejs, więc ten komentarz nie jest nawet wyświetlany w etykietkach narzędzi podczas kodowania.

Edytować:

Jeśli chcesz zobaczyć dokumenty, gdy dzwonisz do klasy bezpośrednio i nie używasz interfejsu, musisz napisać go dwukrotnie lub użyć narzędzia takiego jak GhostDoc.


4

Wypróbuj GhostDoc ! Mi to pasuje :-)

Edycja: Teraz, gdy zostałem poinformowany o wsparciu Sandcastle dla <inheritdoc/>, popieram post Noldorina. To znacznie lepsze rozwiązanie. Jednak nadal ogólnie polecam GhostDoc.


6
Osobiście nie lubię GhostDoc. Generuje dokumentację tam, gdzie w rzeczywistości jej nie ma. To ukrywa fakt, że coś nie jest udokumentowane. Tylko osobista opinia, nie mówię, że ogólnie jest to coś złego.
Stefan Steinegger

1
Zgadzam się z komentarzem Stefana w tym, że GhostDoc nie jest doskonały, jednak automatycznie pobiera „odziedziczone” komentarze, takie jak ten, więc jest to całkiem dobra odpowiedź na to pytanie.
Steve

Stefanie, nie zgadzam się - wręcz przeciwnie, ponieważ GhostDoc odzwierciedla tylko dokumentację, którą już „umieściłeś” w nazwach swoich członków (budując prozę z nazwisk), generuje tylko dokumentację, w której dokumentacja już istnieje (domyślnie). W związku z tym nic nie „produkuje”, ale wygenerowana proza ​​jest doskonałym punktem wyjścia, do którego można dodać rzeczywistą wartość. Prawdziwa dokumentacja nadal wymaga trochę pracy.
Tor Haugen

2

Mam lepszą odpowiedź: FiXml . , Jestem jednym z jego autorów

Klonowanie jest z pewnością działającym podejściem, ale ma istotne wady, np .:

  • Kiedy oryginalny komentarz zostanie zmieniony (co często się zdarza podczas programowania), jego klon nie.
  • Tworzysz ogromne ilości duplikatów. Jeśli korzystasz z jakichkolwiek narzędzi do analizy kodu źródłowego (np. Duplicate Finder w Team City), znajdziesz głównie Twoje komentarze.

Jak zostało wspomniane, <inheritdoc>w Sandcastle znajduje się tag , ale ma on kilka wad w porównaniu z FiXml:

  • Sandcastle tworzy skompilowane pliki pomocy HTML - normalnie nie modyfikuje .xmlplików zawierających wyodrębnione komentarze XML (w końcu nie można tego zrobić "w locie" podczas kompilacji).
  • Implementacja Sandcastle jest mniej wydajna. Np <see ... copy="true" />. Nie .

Więcej informacji można znaleźć w <inheritdoc>opisie Sandcastle .

Krótki opis FiXml: jest to postprocesor dokumentacji XML stworzony przez C # \ Visual Basic .Net. Jest zaimplementowany jako zadanie MSBuild, więc dość łatwo można go zintegrować z dowolnym projektem. Dotyczy kilku irytujących przypadków związanych z pisaniem dokumentacji XML w tych językach:

  • Brak obsługi dziedziczenia dokumentacji z klasy bazowej lub interfejsu. Oznacza to, że dokumentacja dla dowolnego zastąpionego elementu członkowskiego powinna być napisana od zera, chociaż zwykle jest pożądane, aby dziedziczyć przynajmniej jej część.
  • Brak obsługi wstawiania często używanych szablonów dokumentacji , takich jak „Ten typ jest singleton - użyj jego <see cref="Instance" />właściwości, aby uzyskać jedyne jego wystąpienie” lub nawet „Inicjuje nowe wystąpienie <CurrentType>klasy”.

Aby rozwiązać wymienione problemy, dostępne są następujące dodatkowe tagi XML:

  • <inheritdoc />, <inherited /> tagi
  • <see cref="..." copy="..." />atrybut w <see/>tagu.

Oto jego strona internetowa i strona pobierania .



1

Zbudowałem bibliotekę do przetwarzania końcowego plików dokumentacji XML, aby dodać obsługę tagu <inheritdoc />.

Chociaż nie pomaga to w przypadku Intellisense w kodzie źródłowym, umożliwia uwzględnienie zmodyfikowanych plików dokumentacji XML w pakiecie NuGet i dlatego współpracuje z Intellisense w przywoływanych pakietach NuGet.

Więcej informacji na www.inheritdoc.io (dostępna bezpłatna wersja).


0

Nie rób tego. Pomyśl o tym w ten sposób - jeśli oba komentarze muszą być przez cały czas takie same, jeden z nich nie jest konieczny. Musi istnieć powód dla komentarza (oprócz jakiegoś dziwnego obowiązku blokowania komentarza każdej funkcji i zmiennej), więc musisz dowiedzieć się, jaki jest ten unikalny powód i udokumentować to.


3
Nie użyłbym tutaj interfejsu, gdybym nie udawał w testach.
Valentin Vasilyev

0

Dzięki ReSharper możesz go skopiować, ale nie sądzę, aby był zsynchronizowany przez cały czas.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.