Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference generic classes and methods in xml documentation

People also ask

Which is the proper commenting method for XML?

To insert XML comments for a code element Type /// in C#, or ''' in Visual Basic.

What is the difference between a generic class and a generic method?

A generic class or structure can contain nongeneric procedures, and a nongeneric class, structure, or module can contain generic procedures. A generic procedure can use its type parameters in its normal parameter list, in its return type if it has one, and in its procedure code.

What is XML comments in C#?

C# documentation comments use XML elements to define the structure of the output documentation. One consequence of this feature is that you can add any valid XML in your documentation comments. The C# compiler copies these elements into the output XML file.

How do you define generic classes?

A Generic class simply means that the items or functions in that class can be generalized with the parameter(example T) to specify that we can add any type as a parameter in place of T like Integer, Character, String, Double or any other user-defined type.


To reference the method:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.

/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary>

BTW, it was present in the MSDN documentation of .Net Framework 2.0 and 3.0, but it disapeared in the version 3.5


TL;DR:

"How would I reference FancyClass<T>?"

   /// <see cref="FancyClass{T}"/>

"What about FancyClass<T>.FancyMethod<K>(T value)?"

   /// <see cref="FancyClass{T}.FancyMethod{K}(T)"/>

"How can I reference a FancyClass<string>?"

   /// <see cref="SomeType.SomeMethod(FancyClass{string})"/>
   /// <see cref="FancyClass{T}"/> whose generic type argument is <see cref="string"/>

While you can reference a method whose signature includes FancyClass<string> (e.g. as a parameter type), you cannot reference such a closed generic type directly. The second example works around that limitation. (This is seen e.g. on the MSDN refence page for the static System.String.Concat(IEnumerable<string>) method). :

XML documentation comment cref rules:

  • Surround the generic type parameter list with curly braces {} instead of with <> angle brackets. This spares you from escaping the latter as &lt; and &gt; — remember, documentation comments are XML!

  • If you include a prefix (such as T: for types, M: for methods, P: for properties, F: for fields), the compiler will not perform any validation of the reference, but simply copy the cref attribute value straight to the documentation XML output. For this reason, you'll have to use the special "ID string" syntax that applies in such files: always use fully-qualified identifiers, and use backticks to reference generic type parameters (`n on types, ``n on methods).

  • If you omit the prefix, regular language naming rules apply: you can drop namespaces for which there's a using statement, and you can use the language's type keywords such as int instead of System.Int32. Also, the compiler will check the reference for correctness.

XML documentation comment cref cheat sheet:

namespace X
{
    using System;

    /// <see cref="I1"/>  (or <see cref="X.I1"/> from outside X)
    /// <see cref="T:X.I1"/>
    interface I1
    {
        /// <see cref="I1.M1(int)"/>  (or <see cref="M1(int)"/> from inside I1)
        /// <see cref="M:X.I1.M1(System.Int32)"/>
        void M1(int p);

        /// <see cref="I1.M2{U}(U)"/>
        /// <see cref="M:X.I1.M2``1(``0)"/>
        void M2<U>(U p);

        /// <see cref="I1.M3(Action{string})"/>
        /// <see cref="M:X.I1.M3(System.Action{System.String})"/>
        void M3(Action<string> p);
    }

    /// <see cref="I2{T}"/>
    /// <see cref="T:X.I2`1"/>
    interface I2<T>
    {
        /// <see cref="I2{T}.M1(int)"/>
        /// <see cref="M:X.I2`1.M1(System.Int32)"/>
        void M1(int p);

        /// <see cref="I2{T}.M2(T)"/>
        /// <see cref="M:X.I2`1.M2(`0)"/>
        void M2(T p);

        /// <see cref="I2{T}.M3{U}(U)"/>
        /// <see cref="M:X.I2`1.M3``1(``0)"/>
        void M3<U>(U p);
    }
}

None of the answers shown so far work completely for me. ReSharper won't convert the see tag into a Ctrl+click-able link (e.g. image here) unless it completely resolves.

If the method in the OP were in a namespace called Test, the completely resolved link to the method shown would be:

<see cref="M:Test.FancyClass`1.FancyMethod``1(`0)"/>

As you may be able to work out, there should only be one backtick before the number of class type parameters, then two backticks before the number of method type parameters, then the parameters are the zero-indexed parameter with the appropriate number of backticks.

So we can see that FancyClass has one class type parameter, FancyMethod has one type parameter, and an object of the FancyClass parameter type will be passed to the method.

As you can more clearly see in this example:

namespace Test
{
    public class FancyClass<A, B>
    {
        public void FancyMethod<C, D, E>(A a, B b, C c, D d, E e) { }
    }
}

The link becomes:

M:Test.FancyClass`2.FancyMethod``3(`0,`1,``0,``1,``2)

Or "Class with two type parameters which has a method with three type parameters where the method parameters are ClassType1, ClassType2, MethodType1, MethodType2, MethodType3"


As an additional note, I didn't find this documented anywhere and I'm not a genius, the compiler told me all this. All you have to do is create a test project, enable XML documentation, then insert the code you want to work out a link for, and put the start of an XML doc comment on it (///):

namespace Test
{
    public class FancyClass<T>
    {
        ///
        public string FancyMethod<K>(T value) { return "something fancy"; }
    }

    public class Test
    {
        public static void Main(string[] args) { }
    }
}

Then build your project, and the outputted XML documentation includes the link in the doc->members->member element under the attribute name:

<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Test</name>
    </assembly>
    <members>
        <member name="M:Test.FancyClass`1.FancyMethod``1(`0)">

        </member>
    </members>
</doc>

Further from the answers by Lasse and T.B.C:

/// <see cref="T:FancyClass`1{T}"/> for more information.

/// <see cref="M:FancyClass`1{T}.FancyMethod`1{K}(T)"/> for more information.

will also provide tooltips correctly, whereas their version renders it with the curly braces.


/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>

/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.