如何在xml文档中引用通用类和方法


198

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

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

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

例如,在另一个类中,我想让用户知道我将返回的实例FancyClass<int>。我该如何为此做一个见识参考资料呢?

Answers:


257

要引用该方法:

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

3
感谢您的回答!它实际上在<see>上的MSDN页面上丢失了:msdn.microsoft.com/en-us/library/acd0tfbe.aspx
2011年

6
我实际上相信它也可以在VS2010工具提示中使用,您需要指出泛型参数的数量,例如“ FancyClass 1{T}.FancyMethod1 {K}(T)”
Stephen Drew

不确定您的意思。我从来没有添加这些,它一直为我工作。您是否有一个不起作用的特定示例?如果是这样,请将其张贴在某个地方(甚至自己提供一个答案。)
Lasse V. Karlsen

@Lasse,请参阅下面的史蒂夫回答和评论。您的答案没有涵盖正确的Intellisense工具提示。
雅各布·贾努斯斯基耶维奇

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

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


4
T的特殊实例呢?喜欢串吗?也许不可能?
Svish

你什么意思?您无法声明特定版本,因此也无法引用它。
Lasse V. Karlsen,

例如,如果某个方法仅返回List <string>。但并不重要:)
Svish

7
是的,我也想知道...写FancyClass {string}时要折磨曲折,而不是写FancyClass {String}时要折弯...
thinkbeforecoding 2009年

6
进行“编码前思考”的上述观察结果的原因是,它不适用于c#别名。例如,您需要使用Int32而不是intSingle而不是floatetc。(在此处输入此信息,以防其他人
偶然发现

27

TL; DR:

“我要怎么引用FancyClass<T>?”

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

“那FancyClass<T>.FancyMethod<K>(T value)呢?”

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

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

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

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

XML文档注释cref规则:

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

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

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

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

如何仅参考T零件?
nawfal

4
想通了:<typeparamref name="T"/>
nawfal

21

到目前为止,没有显示出对我完全有效的答案。除非完全解决,否则ReSharper不会将see标签转换为可Ctrl点击的链接(例如图片在这里)。

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

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

您可能会发现,在类类型参数数量之前应该只有一个反引号,在方法类型参数数量之前应该只有两个反引号,然后这些参数是带有适当数量的反引号的零索引参数。

因此,我们可以看到FancyClass具有一个类类型参数,FancyMethod具有一个类型参数,并且FancyClass参数类型的对象将传递给该方法。

如您在此示例中可以更清楚地看到:

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

链接变为:

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

或“与具有三个类型参数的方法2型参数类其中该方法的参数是ClassType1ClassType2MethodType1MethodType2MethodType3


另外要注意的是,我在任何地方都找不到此文档,而且我也不是天才,编译器告诉我了这一切。您所要做的就是创建一个测试项目,启用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) { }
    }
}

然后构建您的项目,输出的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>

3
这应该得到更多的支持,尤其是因为无需进行反复试验就能找到正确的符号的技巧。尊敬的我的男人
彼得

10

从Lasse和TBC的答案来看:

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

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

也会正确提供工具提示,而其版本会使用花括号将其显示。


2
使用<see cref =“ System.Collections.Generic.List 1{T}"/>** causes a build-time warning: **XML comment on 'Blah' has syntactically incorrect cref attribute 'System.Collections.Generic.List1 <T> -您是否愿意详细说明应如何使用它?
Jakub Januszkiewicz 2012年

2
嗨,雅各布,这确实似乎不起作用。我还可以使工具提示正常工作的唯一方法是<see cref =“ T:<fullTypeName>`1 {T}” /> />。
斯蒂芬·德鲁

2
好吧,我部分地明白了。如果方法本身不是通用的(例如在List <T> .Add()中),则可以使用:<see cref =“ M:System.Collections.Generic.List`1 {T} .Add(T)” /> 。
雅各布·贾努斯斯基耶维奇

1
似乎不适合我。我在注释标头中有<see cref =“ M:System.Collections.Generic.List`1 {T}” />,以表示我编写的通用扩展方法(将ArrayList转换为List <T>),但ReSharper对其进行了标记因为是语法错误,因此IntelliSense只会逐字显示它。VS 2010 / R#6.1.37.86
Mike Loux 2013年

8
啊哈!我能够使<see cref =“ T:System.Collections.Generic.List`1” />“正常工作。因此,使用T:代替花括号就可以了。它确实扩展了整个名称空间, –如果您不包含名称空间,则该技巧将不起作用,因此它并不完美,但可以实现
Mike Loux 2013年

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

3
请注意,其他答案涵盖了如何引用泛型类,此答案向您展示了如何自行引用类型参数,而这正是我要执行的操作。
jrh

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.