case HtmlNodeType.Document: Inheriting comments from an interface in an implementing class?

ConvertContentTo(node, outText, textInfo);

Suppose I have this interface

public interface IFoo
{
///<summary>
/// Foo method
///</summary>
void Foo();


///<summary>
/// Bar method
///</summary>
void Bar();


///<summary>
/// Situation normal
///</summary>
void Snafu();
}
break;

And this class

public class Foo : IFoo
{
public void Foo() { ... }
public void Bar() { ... }
public void Snafu() { ... }
}
case HtmlNodeType.Text:

Is there a way, or is there a tool that can let me automatically put in the comments of each member in a base class or interface?

// script and style must not be output

Because I hate re-writing the same comments for each derived sub-class!

90373 次浏览
string parentName = node.ParentNode.Name;

GhostDoc does exactly that. For methods which aren't inherited, it tries to create a description out of the name.

if ((parentName == "script") || (parentName == "style")) {

FlingThing() becomes "Flings the Thing"

break;

Use /// <inheritdoc/> if you want inheritance. Avoid GhostDoc or anything like that.

}

I agree it is annoying that comments are not inherited. It would be a fairly simple add-in to create if someone had the time (i wish i did).

// get text

That said, in our code base we put XML comments on the interfaces only and add extra implementation comments to the class. This works for us as our classes are private/internal and only the interface is public. Any time we use the objects via the interfaces we have full comments display in intellisence.

html = ((HtmlTextNode)node).Text; // is it in fact a special closing node output as text?

GhostDoc is good start and has made the process easier to write comments. It is especially useful keeping comments up-to-date when you add/remove parameters, re-run GhostDoc and it will update the description.

if (HtmlNode.IsOverlappedClosingElement(html)) {

Java has this, and I use it all the time. Just do:

/**
* {@inheritDoc}
*/
break;

And the Javadoc tool figures it out.

}

C# has similar marker:

<inheritDoc/>
// check the text is meaningful and not a bunch of whitespaces

You can read more here:

if (html.Length == 0) { break;

http://www.ewoodruff.us/shfbdocs/html/79897974-ffc9-4b84-91a5-e50c66a0221d.htm

}

ReSharper has an option to copy the comments from the base class or interface.

if (!textInfo.WritePrecedingWhiteSpace || textInfo.LastCharWasSpace) {

You can always use the <inheritdoc /> tag:

public class Foo : IFoo
{
/// <inheritdoc />
public void Foo() { ... }
/// <inheritdoc />
public void Bar() { ... }
/// <inheritdoc />
public void Snafu() { ... }
}
html = html.TrimStart();

Using the cref attribute, you can even refer to an entirely different member in an entirely different class or namespace!

public class Foo
{
/// <inheritdoc cref="System.String.IndexOf" />
public void Bar() { ... } // this method will now have the documentation of System.String.IndexOf
}
if (html.Length == 0) { break; }

Another way is to use the <see /> XML documentation tag. textInfo.IsFirstTextOfDocWritten.Value = textInfo.WritePrecedingWhiteSpace = true; } outText.Write(HtmlEntity.DeEntitize(Regex.Replace(html.TrimEnd(), @"\s{2,}", " "))); if (textInfo.LastCharWasSpace = char.IsWhiteSpace(html[html.Length - 1])) { outText.Write(' '); } This is some extra effort but works out of the box...

break; case HtmlNodeType.Element: string endElementString = null; bool isInline; bool skip = false; int listIndex = 0;

Here are some examples:

/// <summary>
/// Implementation of <see cref="IFoo"/>.
/// </summary>
public class Foo : IFoo
{
/// <summary>
/// See <see cref="IFoo"/>.
/// </summary>
public void Foo() { ... }


/// <summary>
/// See <see cref="IFoo.Bar"/>
/// </summary>
public void Bar() { ... }


/// <summary>
/// This implementation of <see cref="IFoo.Snafu"/> uses the a caching algorithm for performance optimization.
/// </summary>
public void Snafu() { ... }
}
switch (node.Name) {

Update:

case "nav": skip = true;

I now prefer to use /// <inheritdoc/> which is now supported by ReSharper.

I ended up creating a tool to post-process the XML documentation files to add support for replacing the <inheritdoc/> tag in the XML documentation files themselves. Available at www.inheritdoc.io (free version available).

I would say to directly use the

/// <inheritdoc cref="YourClass.YourMethod"/>  --> For methods inheritance

And

/// <inheritdoc cref="YourClass"/>  --> For directly class inheritance
isInline = false;

You have to put this comments just on the previous line of your class/method

break;

This will get the info of your comments for example from an interface that you have documented like :

    /// <summary>
/// This method is awesome!
/// </summary>
/// <param name="awesomeParam">The awesome parameter of the month!.</param>
/// <returns>A <see cref="AwesomeObject"/> that is also awesome...</returns>
AwesomeObject CreateAwesome(WhateverObject awesomeParam);
case "body":

Well, there is a kind of native solution, I found for .NET Core 2.2

case "section":

The idea is to use <include> tag.

You can add <GenerateDocumentationFile>true</GenerateDocumentationFile> your .csproj a file.

case "article":

You might have an interface:

namespace YourNamespace
{
/// <summary>
/// Represents interface for a type.
/// </summary>
public interface IType
{
/// <summary>
/// Executes an action in read access mode.
/// </summary>
void ExecuteAction();
}
}
case "aside":

And something that inherits from it:

using System;


namespace YourNamespace
{
/// <summary>
/// A type inherited from <see cref="IType"/> interface.
/// </summary>
public class InheritedType : IType
{
/// <include file='bin\Release\netstandard2.0\YourNamespace.xml' path='doc/members/member[@name="M:YourNamespace.IType.ExecuteAction()"]/*'/>
public void ExecuteAction() => Console.WriteLine("Action is executed.");
}
}
case "h1": case "h2":

Ok, it is a bit scary, but it does add the expected elements to the YourNamespace.xml.

case "header":

If you build Debug configuration, you can swap Release for Debug in the file attribute of include tag.

case "footer":

To find a correct member's name to reference just open generated Documentation.xml file.

case "address":

I also assume that this approach requires a project or solution to be build at least twice (first time to create an initial XML file, and the second time to copy elements from it to itself).

case "main":

The bright side is that Visual Studio validates copied elements, so it is much easier to keep documentation and code in sync with interface/base class, etc (for example names of arguments, names of type parameters, etc).

case "div":

At my project, I have ended up with both <inheritdoc/> (for DocFX) and <include/> (For publishing NuGet packages and for validation at Visual Studio):

        /// <inheritdoc />
/// <include file='bin\Release\netstandard2.0\Platform.Threading.xml' path='doc/members/member[@name="M:Platform.Threading.Synchronization.ISynchronization.ExecuteReadOperation(System.Action)"]/*'/>
public void ExecuteReadOperation(Action action) => action();
case "p": // stylistic - adjust as you tend to use

End the question:
if (textInfo.IsFirstTextOfDocWritten) { This feature has been added at VS2019 v16.4.

outText.Write("\r\n");

https://developercommunity.visualstudio.com/t/608809#T-N875117

}

It works on the interfeace and abstruct class overrideable members