C# 如何在 xml 文档中引用泛型类和方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/532166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:03:30  来源:igfitidea点击:

How to reference generic classes and methods in xml documentation

c#genericsreferencexml-documentation

提问by Svish

When writing xml documentation you can use <see cref="something">something</see>, which works of course. But how do you reference a class or a method with generic types?

在编写 xml 文档时,您可以使用<see cref="something">something</see>,这当然有效。但是如何引用具有泛型类型的类或方法呢?

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

If I was going to write xml documentation somewhere, how would I reference the fancy class? how can I reference a FancyClass<string>? What about the method?

如果我要在某处编写 xml 文档,我将如何引用这个花哨的类?我如何引用 a FancyClass<string>?方法呢?

For example in a different class I wanted to let the user know that I will return an instance of FancyClass<int>. How could I make a see cref thing for that?

例如,在另一个类中,我想让用户知道我将返回FancyClass<int>. 我怎么能为此做一个查看 cref 的东西?

采纳答案by Lasse V. Karlsen

To reference the method:

要引用该方法:

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

回答by thinkbeforecoding

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

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

顺便说一句,它出现在.Net Framework 2.03.0的 MSDN 文档中,但它在3.5 版中消失了

回答by Stephen Drew

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

进一步来自 Lasse 和 TBC 的回答:

/// <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.

还将正确提供工具提示,而他们的版本则使用花括号呈现它。

回答by Max Toro

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

回答by MrLore

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.

到目前为止显示的答案都没有完全适合我。ReSharper 不会将 see 标记转换为Ctrl+click-able 链接(例如图像在这里),除非它完全解析。

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

如果 OP 中的方法位于名为 的命名空间中Test,则显示的方法的完全解析链接将是:

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

<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 FancyClasshas one class type parameter, FancyMethodhas one type parameter, and an object of the FancyClassparameter type will be passed to the method.

所以我们可以看到,FancyClass有一个类类型参数,FancyMethod有一个类型参数,FancyClass会传递一个该参数类型的对象给方法。

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)

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"

或“具有两个类型参数的类,该类具有具有三个类型参数的方法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 (///):

作为附加说明,我没有在任何地方找到这方面的记录,而且我也不是天才,编译器告诉了我这一切。您所要做的就是创建一个测试项目,启用 XML 文档,然后插入要为其计算链接的代码,并在其上添加 XML 文档注释的开头 ( ///):

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->memberelement under the attribute name:

然后构建您的项目,输出的 XML 文档在属性下的doc-> members->member元素中包含链接name

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

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

回答by JohnL4

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

回答by stakx - no longer contributing

TL;DR:

特尔;博士:

"How would I reference FancyClass<T>?"

“我该如何参考FancyClass<T>?”

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

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

“怎么样FancyClass<T>.FancyMethod<K>(T value)?”

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

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

“我如何引用 a FancyClass<string>?”

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

While you canreference a method whose signature includes FancyClass<string>(e.g. as a parameter type), you cannotreference 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). :

尽管你可以参考其签名的方法包括FancyClass<string>(例如,作为参数类型),则不能引用这样的直接关闭通用类型。第二个示例解决了该限制。(这可以在静态System.String.Concat(IEnumerable<string>)方法MSDN 参考页面上看到)。:

XML documentation comment crefrules:

XML 文档注释cref规则:

  • 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 crefattribute value straight to the documentation XML output. For this reason, you'll have to use the special "ID string" syntaxthat applies in such files: always use fully-qualified identifiers, and use backticks to reference generic type parameters (`non types, ``non methods).

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

  • 用大括号{}代替<>尖括号将泛型类型参数列表括起来。这备件你逃跑后者为&lt;&gt;-记住,文档注释XML!

  • 如果包含前缀(例如T:对于类型、M:方法、P:属性、F:字段),编译器将不会对引用执行任何验证,而只是将cref属性值直接复制到文档 XML 输出中。因此,您必须使用适用于此类文件的特殊“ID 字符串”语法:始终使用完全限定的标识符,并使用反引号引用泛型类型参数(`n在类型上、``n在方法上)。

  • 如果省略前缀,则适用常规语言命名规则:您可以删除有using语句的名称空间,并且可以使用语言的类型关键字,例如int代替System.Int32。此外,编译器将检查引用的正确性。

XML documentation comment crefcheat sheet:

XML 文档注释cref备忘单:

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);
    }
}