17

StyleCop rule SA1600 demands that every type member has it's own documentation header. I think it's quite reasonable and I like this rule. But suppose we have the following hierarchy:

/// <summary>
/// Documentation for interface ISomeModule.
/// </summary>
interface ISomeModule
{
    /// <summary>
    /// Documentation for DoA.
    /// </summary>
    void DoA();

    /// <summary>
    /// Documentation for DoB.
    /// </summary>
    void DoB();
}

/// <summary>
/// Documentation for StandardModule.
/// </summary>
class StandardModule : ISomeModule
{
    private readonly SomeCoolType _value;

    /// <summary>
    /// Documentation for constructor.
    /// </summary>
    public StandardModule(SomeCoolType value)
    {
        _value = value;
    }

    // SA1600 violation here!
    public void DoA()
    {
        // realisation of DoA().
    }

    // SA1600 violation here!
    public void DoB()
    {
        // realisation of DoB().
    }

    /// <summary>
    /// Documentation for MyOwnDoC.
    /// </summary>
    public void MyOwnDoC()
    {
        // realisation of MyOwnDoC().
    }
}

Here, I fully documented interface members DoA() and DoB(), we know what these methods exactly do from the interface documentation. VS Intellisence knows it too and we can see description of methods by hovering mouse over these methods even in class StandardModule. So it is not necessary to copy documentation from interface to derived class. But StyleCop demands to do it. Why? Does anybody know?

If we try to solve this issue, we can go 4 different ways:

1. Copy documentation from interface. The problem here is if we copy documentation we will meet the issue of updating documentation in all derived classes if interface behaviour changes.

2. Suppress message with SuppressMessageAttribute. Well, suppose we say "Ok, I can use SuppressMessageAttribute" to suppress this violation I don't agree with. And I prepend class StandardModule with SuppressMessageAttribute for rule SA1600. But now StyleCop stops checking for documentation headers in class StandardModule at all. I don't want it, because we have constructor and some other methods.

3. Divide class into regions, We can divide class StandardModule into 2 regions and use message suppression only on the part that implements interface ISomeModule. And I think that all parts should be placed into one file. I like this approach most of all (after the way #4), but now we have to deal with multiple parts of one class.

4. Modify rule SA1600. Is it possible to make my own implementation of rule SA1600 so that it takes into account whether class members were documented in a base class or in interface? (here I don't ask if we can write our own rule for StyleCop, I know we can, but I mean whether StyleCop engine can check if some members came from interface or base class).

What is the most preferable way to solve SA1600 problem on interface realisation?

Dmitrii Lobanov
  • 4,897
  • 1
  • 33
  • 50

2 Answers2

9

The upcoming StyleCop 4.4.1 release is supposed to support the inheritdoc tag. If you're willing to use a documentation-generation tool that supports this tag (e.g.: Sandcastle or FiXml), you might have a working solution that would address both your concerns.

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
  • 1
    Great! BTW, here's the link to this feature: http://stylecop.codeplex.com/workitem/6637. And the good news that we can use 4.4.1 Preview by now! – Dmitrii Lobanov Jan 20 '11 at 13:19
  • Looks like VS 2008 Intellisence doesn't like the inheritdoc tag, because if I prepend members with inheritdoc tag, VS 2008 doesn't display documentation from interface on members hovering with mouse, it just shows member signature (name, parameters, return type). Perhaps VS 2010 knows how to handle inheritdoc properly? What can be done? – Dmitrii Lobanov Jan 21 '11 at 07:16
  • @Dmitry: Neither the 2008 or 2010 C# compilers are aware of the inheritdoc tag. As mentioned in my original answer, you will need you will need to use an additional tool in order for the tag to be consumed so that inherited doucmentation is inserted in the intellisense-supporting xml file. – Nicole Calinoiu Jan 21 '11 at 12:24
  • well, I saw an issue at R# web site, somebody posted request to implement support for inheritdoc tag a long time ago. All we can do is to wait :) – Dmitrii Lobanov Jan 21 '11 at 20:39
8

It never occured to me that this would be a problem because I always regarded the documentation of the declaration of an interface as something different than the documentation of the implementation of this interface.

I may be wrong but I'm happy to learn.

My actual answer to your question would be: 1) Copy Translate documentation from interface.

Filburt
  • 17,626
  • 12
  • 64
  • 115
  • 1
    then I would need to keep classes documentation synchronised to interface documentation, thus adding one more step in process of changing and writing code. I think that documentation doubling is doubling, and if we try to avoid doubling in code, why we want to introduce doubling in something else like documentation. Doubling is evil :) – Dmitrii Lobanov Jan 20 '11 at 12:21
  • @Dmitry I totally agree that doubling is evil. But changing the interface should result in an update to your doc the same as changing the implementation. I see the first one as documenting what is supposed to happen wheras the second as to how it make it happen. If you feel strongly against repeating yourself and think along the lines of Robert "Uncle Bob" C. Martin's "Clean Code" your best choice would be to suppress the message. – Filburt Jan 20 '11 at 12:34
  • @Dmitry If you look at it in a way of you having to comply with a rule that actually doesn't add any value to your code the answer should be clear: Turn off/suppress this rule instead of heading towards working around it and ending up with documentation that lies. – Filburt Jan 20 '11 at 12:39