Załóżmy, że mam ten interfejs
public interface IFoo
{
///<summary>
/// Foo method
///</summary>
void Foo();
///<summary>
/// Bar method
///</summary>
void Bar();
///<summary>
/// Situation normal
///</summary>
void Snafu();
}
I ta klasa
public class Foo : IFoo
{
public void Foo() { ... }
public void Bar() { ... }
public void Snafu() { ... }
}
Czy jest sposób lub czy istnieje narzędzie, które pozwala mi automatycznie umieszczać komentarze każdego elementu członkowskiego w klasie bazowej lub interfejsie?
Ponieważ nienawidzę ponownego pisania tych samych komentarzy dla każdej pochodnej podklasy!
c#
inheritance
comments
Jumpinjackie
źródło
źródło
Odpowiedzi:
GhostDoc robi dokładnie to. W przypadku metod, które nie są dziedziczone, próbuje utworzyć opis z nazwy.
FlingThing()
staje się"Flings the Thing"
źródło
<summary>
,<param>
,<returns>
,<throws>
,etc...
sekcje dla Ciebie. Wiele razy z wystarczająco dobrymi wynikami; innym razem wymaga poprawek lub rozszerzenia, ale nadal zmniejsza ogólny wysiłek.Zawsze możesz użyć
<inheritdoc />
tagu:public class Foo : IFoo { /// <inheritdoc /> public void Foo() { ... } /// <inheritdoc /> public void Bar() { ... } /// <inheritdoc /> public void Snafu() { ... } }
Używając
cref
atrybutu, możesz nawet odwołać się do zupełnie innego członka w zupełnie innej klasie lub przestrzeni nazw!public class Foo { /// <inheritdoc cref="System.String.IndexOf" /> public void Bar() { ... } // this method will now have the documentation of System.String.IndexOf }
źródło
Użyj,
/// <inheritdoc/>
jeśli chcesz dziedziczyć. Unikaj GhostDoc lub czegoś podobnego.Zgadzam się, że to denerwujące, że komentarze nie są dziedziczone. Byłby to dość prosty dodatek do stworzenia, gdyby ktoś miał czas (żałuję, że nie miał).
To powiedziawszy, w naszej bazie kodu umieszczamy komentarze XML tylko na interfejsach i dodajemy dodatkowe komentarze dotyczące implementacji do klasy. To działa dla nas, ponieważ nasze zajęcia są prywatne / wewnętrzne i tylko interfejs jest publiczny. Za każdym razem, gdy używamy obiektów przez interfejsy, mamy pełne komentarze wyświetlane w inteligencji.
GhostDoc to dobry początek i ułatwił proces pisania komentarzy. Szczególnie przydatne jest utrzymywanie aktualności komentarzy podczas dodawania / usuwania parametrów, ponownego uruchamiania GhostDoc i aktualizowania opisu.źródło
<param name="origin">The origin.</param>
. Zobacz ghostdoc mówi najgorsze rzeczy, aby uzyskać więcej przykładów. Program Visual Studio ma teraz znacznie lepsze lintowanie i generatory dla xmldocs, aby poinformować Cię, gdy parametry + dokumenty nie są wyrównane, więc GhostDoc (lub inne narzędzia) nie są już potrzebne.Java to ma i używam go cały czas. Po prostu zrób:
/** * {@inheritDoc} */
Narzędzie Javadoc rozwiązuje to.
C # ma podobny znacznik:
Możesz przeczytać więcej tutaj:
http://www.ewoodruff.us/shfbdocs/html/79897974-ffc9-4b84-91a5-e50c66a0221d.htm
źródło
<inheritdoc/>
znacznika: Sandcastle go ma. shfb.codeplex.comPowiedziałbym, aby bezpośrednio użyć
/// <inheritdoc cref="YourClass.YourMethod"/> --> For methods inheritance
I
/// <inheritdoc cref="YourClass"/> --> For directly class inheritance
Musisz umieścić ten komentarz w poprzednim wierszu swojej klasy / metody
Spowoduje to uzyskanie informacji o twoich komentarzach, na przykład z interfejsu, który udokumentowałeś, takiego jak:
/// <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);
źródło
Resharper ma opcję kopiowania komentarzy z klasy bazowej lub interfejsu.
źródło
Innym sposobem jest użycie
<see />
znacznika dokumentacji XML. To dodatkowy wysiłek, ale działa po wyjęciu z pudełka ...Oto kilka przykładów:
/// <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() { ... } }
Aktualizacja:
Wolę teraz używać tego,
/// <inheritdoc/>
który jest teraz obsługiwany przez ReSharper.źródło
Skończyło się na stworzeniu narzędzia do końcowego przetwarzania plików dokumentacji XML, aby dodać obsługę zastępowania
<inheritdoc/>
znacznika w samych plikach dokumentacji XML. Dostępne na www.inheritdoc.io (dostępna bezpłatna wersja).źródło
Cóż, jest coś w rodzaju natywnego rozwiązania, które znalazłem dla .NET Core 2.2
Chodzi o to, aby użyć
<include>
tagu.Możesz dodać
<GenerateDocumentationFile>true</GenerateDocumentationFile>
swój.csproj
plik.Możesz mieć interfejs:
namespace YourNamespace { /// <summary> /// Represents interface for a type. /// </summary> public interface IType { /// <summary> /// Executes an action in read access mode. /// </summary> void ExecuteAction(); } }
I coś, co po nim dziedziczy:
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, jest to trochę przerażające, ale dodaje oczekiwane elementy do
YourNamespace.xml
.Jeśli budować
Debug
konfigurację, można zamienićRelease
naDebug
wfile
atrybucieinclude
znacznika.Aby znaleźć poprawne
member
„sname
odwołać wystarczy otworzyć wygenerowanyDocumentation.xml
plik.Zakładam również, że takie podejście wymaga co najmniej dwukrotnego zbudowania projektu lub rozwiązania (za pierwszym razem do utworzenia początkowego pliku XML, a za drugim do skopiowania z niego elementów do siebie).
Jasną stroną jest to, że Visual Studio sprawdza poprawność skopiowanych elementów, więc znacznie łatwiej jest zsynchronizować dokumentację i kod z interfejsem / klasą bazową itp. (Na przykład nazwy argumentów, nazwy parametrów typu itp.).
W moim projekcie skończyło się na obu
<inheritdoc/>
(dla DocFX) i<include/>
(Do publikowania pakietów NuGet i do walidacji w 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();
źródło