Documenting overloaded methods with the same XML comments
Asked Answered
E

5

40

Say I have this constructor:

/// <summary>
/// Example comment.
/// </summary>
public SftpConnection(string host, string username, 
    string password, int port) {...}

which has these overloads:

public SftpConnection(string host, string username, string password) 
    : this(host, username, password, 22) { }

public SftpConnection(string host, string username, int port) 
    : this(host, username, "", port) { }

public SftpConnection(string host, string username) 
    : this(host, username, "", 22) { }

and in reality, the XML comment is pretty large, with param, example and exception elements and so on.

Is there some way to add a special XML comment one-liner to the overloads, such that they use the exact same comments so that I don't need to copy-paste the whole, enormous original comments?

I'm thinking something like: <use cref="SftpConnection(string,string,string,int)" /> which doesn't work of course.

I am aware of the include element, but I get the impression it reads the comments from an XML file instead, which I don't want - I want the comment to still be visible in the code, but only once.

Thanks :-)

Ermelindaermengarde answered 8/9, 2010 at 12:37 Comment(4)
This question is quite old - for newcommers googling "inheritdoc" should hopefully set you down a path where you'll find the answer you seek. (It depends on your options and requiements.)Horsecar
@Horsecar You should post your comment as an answer, it's actually very useful.Ruffner
@Ruffner <inheritdoc /> doesn't answer this question. It inherits a whole xmldoc comment block, not specific param comments from an overloaded method (or constructor). This question is still quite valid as I've not been able to find a satisfactory answer aside from the workaround suggested by Timwi below.Timberwork
@Horsecar Um, yes. InheritDoc is exactly the answer I was looking for. And yes, it does inherit specific param comments on overloaded methods. And yes, you can add individual params after it for unique parameters. No more copy/pasting comments! Thank you!Zealous
E
24

You can’t really do this. I find it annoying too.

However, you can alleviate the problem by using default parameter values instead of lots of overloads. Instead of:

public SftpConnection(string host, string username, string password, int port)
public SftpConnection(string host, string username, string password)
public SftpConnection(string host, string username, int port)
public SftpConnection(string host, string username)

You can have just a single one:

public SftpConnection(string host, string username, string password = "",
                      int port = 22)

This has multiple advantages:

  • Need only one XML comment. The whole point of my answer. ☺

  • Users of Visual Studio can instantly see that the default value for port is 22. With the overloads, this is not obvious; you have to specifically mention it in the documentation.

  • You indirectly encourage client code to become more readable by encouraging the use of named parameters (e.g. port: 2222 instead of just 2222, which is less clear).

And the greatest part about this is that using default values does not remove the ability to still have several overloads if you need them. Typical examples where you want overloads with default values might be something like...

ReadFrom(string filename, ReaderOptions options = null)
ReadFrom(Stream stream, ReaderOptions options = null)
ReadFrom(byte[] rawData, ReaderOptions options = null)

In these cases, I would argue the XML comments should actually be different.

Emilyemina answered 8/9, 2010 at 13:7 Comment(9)
You're right about that. I have changed my code as you suggested. Nevertheless, this is going to bug me now in the future! And there must be other situations where this functionality is needed.Ermelindaermengarde
Definitely. Like I said, I find it annoying too. Default values only alleviate the problem, not solve it...Emilyemina
@Tergiver: Of course. I don’t normally consider it necessary to say because it’s not that common that people have to use something obsolete.Emilyemina
@Timwi: Actually I find it very common that people use the older versions of .NET For some strange reason companies have a hard time moving over to new technologies sometimes. I for example am still using 3.5 for work.Malvie
@Adkins: You can use this with .NET 3.5 just fine. I never mentioned .NET. You only need a C# 4.0 compiler.Emilyemina
Can someone address the concerns about using defaults rather than overloads raised in this Microsoft article? msdn.microsoft.com/en-us/library/vstudio/…Barbicel
@JoshuaGruber: I think the only relevant guideline in the article is the last one, where they're warning you the technique above is not CLS-compliant. So I would say it's fine if you stick to VB.NET / C#, but less so if you need to expose your functions to other languages.Halleyhalli
If you have ref parameters then you must overload. Unless you're using VB.net, then you can have optional byref.Zealous
@Timwi: Looks like I can not reproduce the problem. Comments deleted.Avaunt
M
27

InheritDoc works perfectly for overloads (at least in VS 2019). You can override any part of it too. Official documentation says:

Inherit XML comments from base classes, interfaces, and similar methods.

/// <summary>
/// Method does something
/// </summary>
/// <param name="someString">Some string</param>
public void SomeMethod(string someString)
{
}

/// <param name="someInt">Some int</param>
/// <inheritdoc cref="SomeMethod(string)"/>
public void SomeMethod(string someString, int someInt)
{
}

/// <summary>Override the summary part</summary>
/// <param name="someString">Description for someString overridden</param>
/// <param name="anotherInt">Another int</param>
/// <inheritdoc cref="SomeMethod(string, int)"/>
public void SomeMethod(string someString, int someInt, int anotherInt)
{
}

/// <typeparam name="TOtherType">Other type</typeparam>
/// <inheritdoc cref="IInterface{TModel,TKey}.SomeMethod{TType}(TType)"/>
public void SomeMethod<TType, TOtherType>(TType first, TOtherType second)
{
}
Mordancy answered 25/5, 2021 at 7:30 Comment(6)
This did not work for me. I tried it on my interface methods. Overloads did not show the summary.Ury
Did you specify the cref attribute? It won't work without it.Mordancy
It works for normal methods but not for methods with genericsReciprocation
Updated my answer to show the syntax when using generics.Mordancy
Sadly can confirm this does not work for VS 2017 (and presumably earlier).Cairo
With Roslyn analyzers, I get CS1573 warnings because the xml comment misses a comment for the arguments that are described in the inherited method. Known issue for Roslyn.Deina
E
24

You can’t really do this. I find it annoying too.

However, you can alleviate the problem by using default parameter values instead of lots of overloads. Instead of:

public SftpConnection(string host, string username, string password, int port)
public SftpConnection(string host, string username, string password)
public SftpConnection(string host, string username, int port)
public SftpConnection(string host, string username)

You can have just a single one:

public SftpConnection(string host, string username, string password = "",
                      int port = 22)

This has multiple advantages:

  • Need only one XML comment. The whole point of my answer. ☺

  • Users of Visual Studio can instantly see that the default value for port is 22. With the overloads, this is not obvious; you have to specifically mention it in the documentation.

  • You indirectly encourage client code to become more readable by encouraging the use of named parameters (e.g. port: 2222 instead of just 2222, which is less clear).

And the greatest part about this is that using default values does not remove the ability to still have several overloads if you need them. Typical examples where you want overloads with default values might be something like...

ReadFrom(string filename, ReaderOptions options = null)
ReadFrom(Stream stream, ReaderOptions options = null)
ReadFrom(byte[] rawData, ReaderOptions options = null)

In these cases, I would argue the XML comments should actually be different.

Emilyemina answered 8/9, 2010 at 13:7 Comment(9)
You're right about that. I have changed my code as you suggested. Nevertheless, this is going to bug me now in the future! And there must be other situations where this functionality is needed.Ermelindaermengarde
Definitely. Like I said, I find it annoying too. Default values only alleviate the problem, not solve it...Emilyemina
@Tergiver: Of course. I don’t normally consider it necessary to say because it’s not that common that people have to use something obsolete.Emilyemina
@Timwi: Actually I find it very common that people use the older versions of .NET For some strange reason companies have a hard time moving over to new technologies sometimes. I for example am still using 3.5 for work.Malvie
@Adkins: You can use this with .NET 3.5 just fine. I never mentioned .NET. You only need a C# 4.0 compiler.Emilyemina
Can someone address the concerns about using defaults rather than overloads raised in this Microsoft article? msdn.microsoft.com/en-us/library/vstudio/…Barbicel
@JoshuaGruber: I think the only relevant guideline in the article is the last one, where they're warning you the technique above is not CLS-compliant. So I would say it's fine if you stick to VB.NET / C#, but less so if you need to expose your functions to other languages.Halleyhalli
If you have ref parameters then you must overload. Unless you're using VB.net, then you can have optional byref.Zealous
@Timwi: Looks like I can not reproduce the problem. Comments deleted.Avaunt
B
5

A half-solution is the <overloads></overloads> tag. While it doesn't solve the issue with <summary/>, it does provide documentation that shows up anywhere all the overloads are listed as a group, including both IntelliSense and SandCastle.

Bloomers answered 3/10, 2012 at 13:50 Comment(0)
M
2

Is this what you want?

/// <seealso cref="SftpConnection(string,string,string,int)"</seealso>
Missing answered 8/9, 2010 at 12:41 Comment(5)
That does not work, but I will look into the seealso element, TY.Ermelindaermengarde
OK, I can't seem to get seealso to do anything. Long shot but is it perhaps something to do with the version of c# or .net?Ermelindaermengarde
I think its meant for creating rich HTML documentations using doxygen and other documentation tools... ill look into what it does, though...what version of VS are you using (or are you using Mono)?Missing
VS 2010 - I think you have to use the fully-qualified names though so your example might not work.Ermelindaermengarde
After looking at visual studio's documentation and trying several workarounds, I have decided that the <seealso></seealso> is for reference only.Missing
B
0

I came from google and I'd like to share my solution based on the discussion above.

Let's assume that you have two methods, one of them is an overload:

public void MethodA(string paramA);
public void MethodA(string paramA, string paramB);

in order to map them to a XML file documentation you'd need to use the following commments:

/// <include file='Docs/MyXMLFile.xml' path='docs/members/MethodA/*'/>
public void MethodA(string paramA);

/// <include file='Docs/MyXMLFile.xml' path='docs/members/MethodA/*'/>
public void MethodA(string paramA, string paramB);

And inside of your XML file, you need to use the <overloads> tag as informed by @Kache, the only thing which is important to note is the hierarchical structure which needs to be respected, so the final solution would be like this:

in the MyXMLFile.xml

<overloads>
<MethodA>
      <summary>
       My MethodA...  
      </summary>
      <param name="paramA">
        My ParamA....
      </param>
</MethodA>
<MethodA>
      <summary>
       My MethodA...  
      </summary>
      <param name="paramA">
        My ParamA....
      </param>
      <param name="paramB">
        My ParamB....
      </param>
</MethodA>
</overloads>
Bil answered 7/10, 2020 at 14:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.