Ugrás a fő tartalomra

Ways to synchronize interface and implementation comments in C# [closed]

Are there automatic ways to sync comments between an interface and its implementation? I'm currently documenting them both and wouldn't like to manually keep them in sync.
UPDATE:
Consider this code:
interface IFoo{
    /// <summary>
    /// Commenting DoThis method
    /// </summary>
    void DoThis();
}
class Foo : IFoo {
    public void DoThis();
}
When I create class like this:
IFoo foo=new Foo();
foo.DoThis();//comments are shown in intellisense
Here comments are not shown:
Foo foo=new Foo();
foo.DoThis();//comments are not shown in intellisense
The <inheritDoc/> tag will perfectly generate the documentation in Sand Castle, but it doesn't work in intellisense tooltips.
Please share your ideas.
Thanks.

closed as primarily opinion-based by TylerH, robinCTS, Kris Roofe, Shiladitya, EJoshuaS Jan 7 at 3:49

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

9 Answers

up vote54down voteaccepted
You can do this quite easily using the Microsoft Sandcastle (or NDoc) inheritdoc tag. It's not officially supported by the specification, but custom tags are perfectly acceptable, and indeed Microsoft chose to copy this (and one or two other tags) from NDoc when they created 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)
{
    //
}
Here is the help page from the Sandcastle Help File Builder GUI, which describes its usage in full.
(Of course, this isn't specifically "synchronisation", as your question mentions, but it would seem to be exactly what you're looking for nonetheless.)
As a note, this sounds like a perfectly fair idea to me, though I've observed that some people think you should always respecify comments in derived and implemented classes. (I've actually done it myself in documenting one of my libraries and I haven't see any problems whatsoever.) There's almost always no reason for the comments to differ at all, so why not just inherit and do it the easy way?
Edit: Regarding your update, Sandcastle can also take care of that for you. Sandcastle can output a modified version of the actual XML file it uses for input, which means you can distribute this modified version along with your library DLL instead of the one built directly by Visual Studio, which means you have the comments in intellisense as well as the documentation file (CHM, whatever).
If you're not using it already, I strongly recommend a free Visual Studio addon called GhostDoc. It eases the documentation process. Have a look at my comment on a somewhat related question.
Although GhostDoc won't make the synchronization automatically, it can help you with the following scenario:
You have a documented interface method. Implement this interface in a class, press the GhostDoc shortcut key, Ctrl-Shift-D, and the XML comment from the interface will be added to the implemented method.
Go to the Options -> Keyboard settings, and assign a key to GhostDoc.AddIn.RebuildDocumentation (I used Ctrl-Shift-Alt-D). alt text http://i44.tinypic.com/10dd1f9.png
Now, if you change the XML comment on the interface, just press this shortcut key on the implemented method, and the documentation will be updated. Unfortunately, this doesn't work vice-versa.
  • The newest version (5.3.16270) of GhostDoc can also create inherited docu. I just tried it for my interface implementations. Nice bonus, it also adds the exceptions with the message of the thrown exception :-) – Christoph Oct 4 '16 at 7:03
I usually write comments like this:
/// <summary>
/// Implements <see cref="IMyInterface.Foo(string, int)"/>
/// </summary>
/// <returns></returns>
The methods are used only by the interface, so this comment is not even shown in tooltips when coding.
Edit:
If you want to see docs when you call the class directly and not using the interface, you need to write it twice or use a tool like GhostDoc.
Try GhostDoc! It works for me :-)
Edit: Now that I've been made aware of Sandcastle's support for <inheritdoc/>, I endorse Noldorin's post. It's a much better solution. I still recommend GhostDoc on a general basis, though.
  • 6
    Personally I don't like GhostDoc. It generates documentation where there is actually none. This is hiding the fact that something is not documented. Just a personal opinion, I don't say that it is something bad in general.– Stefan Steinegger May 5 '09 at 9:17
  • 1
    Agree with comment from Stefan in that GhostDoc isn't perfect, however it does automatically pull in "inherited" comments like this so it is a pretty good answer to the question. – Steve Haigh May 5 '09 at 9:25
  • Stefan, I disagree - on the contrary, because GhostDoc only reflects the documentation you've already "put" into your member names (by building prose from the names), it only generates documentation where documentation already exists (implicitly). As such, it 'produces' nothing, but the generated prose is an excellent starting point to which you can add actual value. Real documentation still takes some work. – Tor Haugen May 5 '09 at 12:35
I have a better answer: FiXml.
Cloning the is certainly working approach, but it has significant disadvantages, e.g.:
  • When the original comment is changed (which frequently happens during development), its clone is not.
  • You're producing huge amount of duplicates. If you're using any source code analysis tools (e.g. Duplicate Finder in Team City), it will find mainly your comments.
As it was mentioned, there is <inheritdoc> tag in Sandcastle, but it has few disadvantages in comparison to FiXml:
  • Sandcastle produces compiled HTML help files - normally it does not modify .xml files containing extracted XML comments (at last, this can't be done "on the fly" during the compilation).
  • Sandcastle's implementation is less powerful. E.g. the is no <see ... copy="true" />.
See Sandcastle's <inheritdoc> description for further details.
Short description of FiXml: it is a post-processor of XML documentation produced by C# \ Visual Basic .Net. It is implemented as MSBuild task, so it's quite easy to integrate it to any project. It addresses few annoying cases related to writing XML documentation in these languages:
  • No support for inheriting the documentation from base class or interface. I.e. a documentation for any overridden member should be written from scratch, although normally it’s quite desirable to inherit at least the part of it.
  • No support for insertion of commonly used documentation templates, such as “This type is singleton - use its <see cref="Instance" /> property to get the only instance of it.”, or even “Initializes a new instance of <CurrentType> class.”
To solve mentioned issues, the following additional XML tags are provided:
  • <inheritdoc />, <inherited /> tags
  • <see cref="..." copy="..." /> attribute in <see/> tag.
Here is its web page and download page.
/// <inheritDoc/>
I built a library to post-process the XML documentation files to add support for the <inheritdoc/> tag.
While it doesn't help with Intellisense in source code, it does allow the modified XML documentation files to be included in a NuGet package and therefore works with Intellisense in referenced NuGet packages.
More info at www.inheritdoc.io (free version available).
With ReSharper you can copy it, but I don't think that it is in sync all the time.
Don't do that. Think of it this way - if both comments are required to be the same all the time, then one of them isn't necessary. There has to be a reason for the comment (besides some kind of weird obligation to comment-block every function and variable) so you need to figure out what that unique reason is and document that.

Megjegyzések

Népszerű bejegyzések ezen a blogon

SW Documentation: Requirements

Requirements Nonfunctional Requirements Q&A FEBRUARY 17, 2010  ~  ANDREW STELLMAN ~  3 COMMENTS Non-functional requirements Q&A: We answer questions from readers about using  nonfunctional requirements  on a real software project, and how to use them on a real software project. Non-functional requirements: Planning out how well your software will work A couple of months ago I wrote a post called  Using nonfunctional requirements to build better software . It’s basically a step-by-step guide for creating an easy, practical technique to use nonfunctional requirements on a real software project, treating them in a way that’s similar to how a lot of Agile teams treat user stories, scenarios and other functional requirements: by sticking them on index cards and using them to do some lightweight planning. Since then, I’ve gotten a lot of questions about nonfunctional requirements (or, as some people call them, non functional requirements...

Privacy Notice for Visitors to Our Users’ Sites

Privacy Notice for Visitors to Our Users’ Sites Sections Who’s Who and What This Privacy Notice Covers Information We Collect About Visitors to Our Users’ Sites Information a Visitor Provides to a Site Information We Automatically Collect from the Site Other Information Provided by Our Users How We Use Visitor Information How We Share Visitor Information Other Tools Other Resources Hi there! This Privacy Notice explains how we, at Automattic, process information about the visitors of our users’ websites in connection with the services we provide through WordPress.com, Jetpack (including WooCommerce Services), IntenseDebate, Polldaddy.com, and Akismet. Read on! Who’s Who and What This Privacy Notice Covers Let’s talk first about who we are at Automattic, what we do, and what this Privacy Notice covers. We are the folks behind a variety of products and services designed to allow anyone–from bloggers, to small business owners, and enterprises–to create, publ...

THE RIGHT WAY TO WRITE A SINGLETON

THE RIGHT WAY TO WRITE A SINGLETON July 17, 2015 by   Hector Matos Even though I've written about the woes of managing state in my previous post, sometimes there's just no way we can avoid it. One example of managing state is something we're all quite acquainted with - The Singleton. The problem we find in Swift is that there are SEVERAL ways of implementing them. But which way is the right way? In this post I'm going to show you the history of the singleton and then show you the right way to implement the singleton in Swift. If you want to see the right way to implement the singleton pattern in Swift along with proof of it's "right-ness", you can scroll to the bottom of the post and see it there. :) A TRIP DOWN MEMORY LANE Swift is a natural evolution of Objective-C. In Objective-C, this is how we implemented the singleton: @interface Kraken : NSObject @end @implementation Kraken + ( instancetype ) sharedInstance { ...