question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

XML Documents for Positional Records don't show example property

See original GitHub issue

VS 17.2.5

This is sort of a follow-up to https://github.com/dotnet/roslyn/issues/52663, where the xml doc for records added the param element to the synthesized property, which is working great. However, to add an example, you still have to redefine the properties so that the output xml has the example in each of the property member elements.

For example, here is a simple record with a single property:

/// <summary>Simple Model</summary>
/// <param name="MyProperty" example="Example string">A basic parameter for a record</param>
public record MyModel(string MyProperty);

The (simplified) xml doc that is created as a result looks like this:

<doc>
    <members>
        <member name="T:MyModel">
            <summary>Simple Model</summary>
            <param name="MyProperty" example="Example string">A basic parameter for a record</param>
        </member>
        <member name="M:MyModel.#ctor(System.String)">
            <summary>Simple Model</summary>
            <param name="MyProperty" example="Example string">A basic parameter for a record</param>
        </member>
        <member name="P:MyModel.MyProperty">
            <summary>A basic parameter for a record</summary>  // Missing the  <example> element
        </member>
    </members>
</doc>

For the <member name="P:MyModel.MyProperty"> element, it doesn’t contain an <example> element, so the documentation (in Swagger for my use case) doesn’t show the proper example.

I can get around this by redefining the property, so the class ends up looking like this:

/// <summary>Simple Model</summary>
public record MyModel(string MyProperty)
{
    /// <summary>A basic parameter for a record</summary>
    /// <example>Example string</example>
    public string MyProperty { get; init; } = MyProperty;  // this is gross
};

This ends up creating the desired XML Doc below:

<doc>
    <members>
        <member name="T:MyModel">
            <summary>Simple Model</summary>
            <param name="MyProperty" example="Example string">A basic parameter for a record</param>
        </member>
        <member name="M:MyModel.#ctor(System.String)">
            <summary>Simple Model</summary>
            <param name="MyProperty" example="Example string">A basic parameter for a record</param>
        </member>
        <member name="P:MyModel.MyProperty">
            <summary>A basic parameter for a record</summary>
            <example>Example string</example>
        </member>
    </members>
</doc>

Expected Behavior: The ideal behavior here would be similar to the previous issue: Copy the example attribute from the model record into the Property member in the XML docs.

Actual Behavior: <param> comments on the record don’t copy the example attribute into the Property element, requiring us to redefine the property in the record.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:4
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
RikkiGibsoncommented, Jul 22, 2022

Before beginning implementation work here let’s verify whether we consider this a bug-fix level change, or a language-level change, etc., get a specific design in place and get buy-in on that design. Tagging @jcouv for visibility.

I’m about to go out of office for a few weeks so won’t be able to assist with this for a while.

0reactions
Markempcommented, Jul 23, 2022

example= in the param tag would be for simple primitives for that parameter, specifically to allow the xml documentation to display an example value instead of the type (string, float, etc). For the simple records shown in the original post, you cut the vertical space from 7 lines to just 3 if you have the ability to define the parameter example on the record.

If your parameter is a more complicated type (a class) or needs more explanation (requiring a <code> block for example), you still have the traditional method of defining a property with the { get; init; } style.

We use records a lot for API requests/responses, and we’d like to keep the records as terse as possible, and for the swagger docs to provide meaningful examples for the API consumers (Widget Name instead of string). However, with the current implementation we have to redefine the parameter into the property. I’m not sure if this changes anything at the compiled code level. It would be interesting to compare the difference between the 2 examples above, but that’s a bit beyond my ability.

Also, there is an edge case where if the properties are explicitly created, and then docs are added on both the record (as param) and the property (as summary), the property doesn’t get added from either source. I’ve added a couple of unit tests (attached as AdditionalTests.cs.txt based off of the PositionalRecord_06 test to demonstrate this. The tests are passing, but probably shouldn’t. (Or just as likely I overlooked something in the test itself… 😳)

            var source = @"
/// <summary>The record.</summary>
/// <param name=""Item"">Item within the record.</param>
record Rec(string Item)
{
    <summary>Item within the record</summary>
    <example>An example</example>
    public string Item { get; init; } = Item;
}
";

I’ve also attached some additional unit tests on how I imagine the example attribute working, in the event this helps with the design.

AdditionalTests.cs.txt AdditionalTestsWithExampleParam.cs.txt

Read more comments on GitHub >

github_iconTop Results From Across the Web

XML Documents for Positional Records · Issue #52663
According to #44571 it should be possible with Visual Studio 16.9 to specify xml documents for auto generated properties based on the primary...
Read more >
How to Document Properties Declared in Positional ...
The workaround is to declare the properties manually. There was some rumor of an xml comment overhaul coming in the future that would...
Read more >
Documentation comments for properties of positional ...
The best workaround right now to document the property and the parameters is to define the property explicitly, whilst keeping the record ......
Read more >
Inherit documentation for positional C# record parameters ...
Hello! This is about documentation and what Visual Studio tool tips show for positional record parameters if there's no specific xml-style documentation there ......
Read more >
Example XML documentation comments
The first example shows how you document a class with different ... add XML comments for properties /// created for positional records, yet....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found