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

Svi*_*ish 190 c# generics reference xml-documentation

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

public class FancyClass<T>
{
  public string FancyMethod<K>(T value) { return "something fancy"; }
}
Run Code Online (Sandbox Code Playgroud)

如果我要在某处写xml文档,我将如何引用这个花哨的类?我该如何参考FancyClass<string>?方法怎么样?

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

ang*_*son 249

要参考方法:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.
Run Code Online (Sandbox Code Playgroud)

  • 我实际上相信它也适用于VS2010工具提示,你需要指出通用参数的数量,例如"FancyClass`1 {T} .FancyMethod`1 {K}(T)" (5认同)
  • 感谢您的回答!实际上,它在&lt;see&gt;上的MSDN页面上丢失了:http://msdn.microsoft.com/en-us/library/acd0tfbe.aspx (2认同)

thi*_*ing 43

/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary>
Run Code Online (Sandbox Code Playgroud)

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

  • 是的,我也想知道...当写FancyClass {string}时,resharpers曲线但是在编写FancyClass {String}时没有... (7认同)
  • 通过"编码前思考"进行上述观察的原因是它不适用于c#别名.例如,您需要使用`Int32`而不是`int`,`Single`而不是`float`等_(将此信息放在这里以防万一其他人偶然发现)_ (6认同)
  • T的特定实例怎么样?像字符串?也许不可能吗? (4认同)

sta*_*ica 22

TL; DR:

"我怎么参考FancyClass<T>?"

   /// <see cref="FancyClass{T}"/>
Run Code Online (Sandbox Code Playgroud)

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

   /// <see cref="FancyClass{T}.FancyMethod{K}(T)"/>
Run Code Online (Sandbox Code Playgroud)

"我怎么能参考FancyClass<string>?"

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

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 弄清楚:`&lt;typeparamref name =“ T” /&gt;` (2认同)

MrL*_*ore 20

到目前为止,所有答案都没有完全适用于我.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) { }
    }
}
Run Code Online (Sandbox Code Playgroud)

链接变为:

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

或"具有两个类型参数,其具有带有三个类型参数其中该方法的参数是方法类ClassType1,ClassType2,MethodType1,MethodType2,MethodType3"


作为一个补充说明,我没有发现任何记录,我不是一个天才,编译告诉我这一切.您所要做的就是创建一个测试项目,启用XML文档,然后插入您想要编写链接的代码,并在其上放置XML doc注释(///):

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

    public class Test
    {
        public static void Main(string[] args) { }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后构建您的项目,输出的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>
Run Code Online (Sandbox Code Playgroud)

  • 这应该得到更多的支持,特别是因为找到正确的符号的技巧,而不必经历反复试验.感谢我的男人 (3认同)

Ste*_*rew 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.
Run Code Online (Sandbox Code Playgroud)

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

  • 啊哈!我能够得到**<see cref ="T:System.Collections.Generic.List`1"/>"**来工作.所以,使用T:代替花括号做了诀窍.它确实扩展了完整的命名空间,如果你不包含命名空间,这个技巧就行不通,所以它并不完美,但它会做到. (8认同)
  • 使用 **&lt;see cref="System.Collections.Generic.List`1{T}"/&gt;** 会导致构建时警告:**关于 'Blah' 的 XML 注释具有语法错误的 cref 属性 'System.Collections. Generic.List`1&lt;T&gt;** - 您是否愿意详细说明应该如何使用它? (2认同)
  • 嗨Jakub,这确实似乎不起作用.我还可以通过<see cref ="T:<fullTypeName>`1 {T}"/>来获取工具提示正常工作的唯一方法. (2认同)
  • 好的,我部分得到了它.如果方法本身不是通用的(如List <T> .Add()),则可以正常工作:<see cref ="M:System.Collections.Generic.List`1 {T} .Add(T)"/> . (2认同)

Joh*_*nL4 6

/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
Run Code Online (Sandbox Code Playgroud)

  • 请注意,其他答案涵盖了如何引用泛型类,此答案向您展示了如何单独引用类型参数,这正是我想要做的。 (4认同)