Question

I'm writing a C# class library with a number of classes with functions that do just about the same stuff. I need to provide XML comments about the function arguments in each class which are very detailed but the same in most cases. Is there a way of reusing XML comments so I don't have to repeat these XML argument definitions all over my assembly?

Here's an example of my classes:

public class IsodoseControl : TestModule
{
    /// <summary>
    /// Verify a control on Isodose dialog
    /// </summary>
    /// <param name="args">  **<-- WHAT I DON'T WANT TO KEEP REPEATING**
    /// Arguments: [Property, Condition, Expected Value, Tolerance]
    ///            Properties: STATE, VALUE, LABEL
    ///            Conditions: Exists, DoesNotExist, IsEnabled, IsDisabled, ...
    ///            Expected Value (optional): blah blah
    ///            Tolerance (optional): blah blah blah
    /// </param>
    public VerifResult VerifyIsodoseControl(string[] args)
    {
        ...
    }
}

public class BeamControl : TestModule
{
    /// <summary>
    /// Verify a control on Beam dialog
    /// </summary>
    /// <param name="args">  **<-- WHAT I DON'T WANT TO KEEP REPEATING**
    /// Arguments: [Property, Condition, Expected Value, Tolerance]
    ///            Properties: STATE, VALUE, LABEL
    ///            Conditions: Exists, DoesNotExist, IsEnabled, IsDisabled, ...
    ///            Expected Value (optional): blah blah
    ///            Tolerance (optional): blah blah blah
    /// </param>
    public VerifResult VerifyBeamControl(string[] args)
    {
        ...
    }
}

Thanks

Was it helpful?

Solution 2

I don't think there's anything in Visual Studio that will help you. Sandcastle has a tag, inheritdoc, that will let you inherit entire blocks of xml comments, or you might also define a sandcastle token that contains your param text, which would let you write something like

/// <summary>
/// Verify a control on Beam dialog
/// </summary>
/// <param name="args"><token>CommonParamInfo</token></param>
/// (...)

Sandcastle was designed specifically for API documentation, and might not be appropriate for your case, though.

OTHER TIPS

"The <include> tag lets you refer to comments in another file that describe the types and members in your source code. "

You could reference the same file from both classes using <include> tags.

/// <include file='comments.xml' path='MyDocs/MyMembers[@name="test"]/*' />
class OneClass {}

/// <include file='comments.xml' path='MyDocs/MyMembers[@name="test"]/*' />
class DifferentClassWithTheSameFunctionality {}

This link provides some examples of using <include>: http://msdn.microsoft.com/en-us/library/9h8dy30z.aspx

You can use <inheritdoc .../> to get pretty close. It seems mainly limited to only reproducing the entire documentation entry, but with that + some careful wording perhaps it can be made to work.

(Slightly modified wording certainly could be much better than documentation gradually falling out of date because of overlooked manual upkeep.)

<inheritdoc>

XML

<inheritdoc [cref=""] [path=""]/>

Inherit XML comments from base classes, interfaces, and similar methods. Using inheritdoc eliminates unwanted copying and pasting of duplicate XML comments and automatically keeps XML comments synchronized.

...

cref: Specify the member to inherit documentation from. Already defined tags on the current member are not overridden by the inherited ones.

path: The XPath expression query that will result in a node set to show. You can use this attribute to filter the tags to include or exclude from the inherited documentation.

...

Reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/recommended-tags#inheritdoc

When you start entering the value for cref your will get intellisense. It is entirely possible (from a quick test I just did) to specify a namespace.classname.methodname there so that it can refer to an entirely different class.

So in the example from the question you could do:

    public class IsodoseControl : TestModule
    {
        /// <summary>
        /// Verify a control on the dialog
        /// </summary>
        /// <param name="args">
        /// Arguments: [Property, Condition, Expected Value, Tolerance]
        ///            Properties: STATE, VALUE, LABEL
        ///            Conditions: Exists, DoesNotExist, IsEnabled, IsDisabled, ...
        ///            Expected Value (optional): blah blah
        ///            Tolerance (optional): blah blah blah
        /// </param>
        public VerifResult VerifyIsodoseControl(string[] args)
        {
            ///...
        }
    }

    public class BeamControl : TestModule
    {
        /// <inheritdoc cref="IsodoseControl.VerifyIsodoseControl" />
        public VerifResult VerifyBeamControl(string[] args)
        {
            // ...
        }
    }

For this to make sense, I just removed the word "Isodose" from the "Verify a control on..." sentence. You'll have to decide in your own code if such a rewording is sufficiently clear.

Here's how the intellisense shows up for VerifyBeamControl() showing the docs: enter image description here


I did not experiment with the path attribute. Examples I saw made it seem pretty unreadable, and for my own use that might be a cure worse than the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top