Search code examples
.netstylecop

StyleCop SA1600 rule and interfaces realisation


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?


Solution

  • 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.