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

发布于 2024-07-13 14:31:02 字数 443 浏览 11 评论 0原文

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

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

如果我要在某个地方编写 xml 文档,我将如何引用这个奇特的类? 如何引用 FancyClass? 方法又如何呢?

例如,在不同的类中,我想让用户知道我将返回 FancyClass 的实例。 我怎样才能为此做一个 see cref 的事情?

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?

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?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

不必了 2024-07-20 14:31:02

参考方法:

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

To reference the method:

/// <see cref="FancyClass{T}.FancyMethod{K}(T)"/> for more information.
红ご颜醉 2024-07-20 14:31:02

长话短说:

“我如何引用 FancyClass?”

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

FancyClass.FancyMethod(T 值)怎么样?”

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

“如何引用 FancyClass?”

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

虽然您可以引用签名包含FancyClass<的方法/code> (例如作为参数类型),您不能直接引用这样的封闭泛型类型。 第二个示例解决了该限制。 (例如,可以在 MSDN 参考页面上看到静态 System.String.Concat(IEnumerable) 方法)。 :

XML文档注释cref规则:

  • 用大括号括住泛型类型参数列表{},而不是用< > 尖括号。 这使您不必将后者转义为 <> — 请记住,文档注释是 XML!

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

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 < and > — 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);
    }
}
素年丶 2024-07-20 14:31:02
/// <summary>Uses a <see cref="FancyClass{T}" /> instance.</summary>

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

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

楠木可依 2024-07-20 14:31:02

到目前为止显示的答案都没有完全适合我。 ReSharper 不会将 see 标签转换为 Ctrl+可点击链接(例如 此处的图片),除非它完全解决。

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

正如您可能能够计算出来的,类类型参数的数量之前应该只有一个反引号,然后是方法类型参数的数量之前应该有两个反引号,然后是参数是具有适当数量的反引号的零索引参数。

所以我们可以看到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)

或“具有两个类型参数的类,该类具有一个具有三个类型参数的方法,其中方法参数为 ClassType1ClassType2MethodType1、< code>MethodType2, MethodType3"


作为补充说明,我没有在任何地方找到此文档,而且我不是天才,编译器告诉了我这一切。 您所要做的就是创建一个测试项目,启用 XML 文档< /a>,然后插入您想要为其建立链接的代码,并在其上放置 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文档包含属性 namedoc->members->member 元素中的链接:

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

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

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>
鸢与 2024-07-20 14:31:02

进一步从 Lasse 和 TBC 的答案来看:

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

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

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

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.

忱杏 2024-07-20 14:31:02
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
/// Here we discuss the use of <typeparamref name="TYourExcellentType"/>.
/// <typeparam name="TYourExcellentType">Your exellent documentation</typeparam>
我恋#小黄人 2024-07-20 14:31:02
/// <see cref="FancyClass<T>.FancyMethod<K>(T)"/> for more information.
/// <see cref="FancyClass<T>.FancyMethod<K>(T)"/> for more information.
定格我的天空 2024-07-20 14:31:02

这是我在其他地方给出的答案。 它也适用于类和方法。

我尝试了有关堆栈溢出的所有方法,以获得在多种情况下工作的结果。 这是一个适合我的解决方案。 (这对于其他人来说是主观的。)

  1. 产生可点击的链接。
  2. 将鼠标悬停在标识符上有效。
  3. 正确生成 .xml 文件。
  4. 智能感知中不会产生错误。
  5. 适用于可为空的泛型类型参数。
  6. 适用于 Resharper 及其内置 XML 文档窗口(Resharper -> 编辑 -> 显示快速文档)
  7. 适用于 Atomineer Pro Documentaion Visual Studio Extension 的 XAM 文档预览。
  8. 适用于泛型类型的泛型类型。

示例#1

  /// <summary>
  ///  This instance field holds a reference to the
  ///  <see cref="ConcurrentDictionary{Decimal, Boolean}"/> as
  ///  <see cref="T:ConcurrentDictionary<decimal, bool?>"/> that contains
  ///  the list of all PDF's that are currently opened and being displayed.
  /// </summary>
  private ConcurrentDictionary<decimal, bool?> openedPdfs = default!;

  Note: 
    The ConcurrentDictionary{Decimal, Boolean} will correctly produce a
    clickable link of ConcurrentDictionary{TKey, TValue} on hovering while
    T:ConcurrentDictionary<decimal, bool?> makes sure the reader gets
    information on what type TKey and TValue are.

示例#2(使用“T”)

  /// <summary>
  ///  This instance field holds a reference to the
  ///  <see cref="ConcurrentDictionary{TKey, TValue}"/> as
  ///  <see cref="T:ConcurrentDictionary<decimal, bool?>"/> that contains
  ///  the list of all PDF's that are currently opened and being displayed.
  /// </summary>
  private ConcurrentDictionary<decimal, bool?> openedPdfs = default!;

Here's an answer I gave somewhere else. It will work for classes and methods too.

I tried everything on stack overflow to a get results that work under several scenarios. Here's a solution that works for me. (That's subjective concerning anyone else.)

  1. Produces clickable links.
  2. Hovering over identifiers works.
  3. Produces .xml file correctly.
  4. Produces no errors in intellisense.
  5. Works for nullable generic type parameters.
  6. Works in Resharper and it's built-in XML Doc window (Resharper -> Edit -> Show Quick Documentation)
  7. Works in XAM Doc Preview for Atomineer Pro Documentaion Visual Studio Extension.
  8. Works with a generic type of a generic type.

Example #1

  /// <summary>
  ///  This instance field holds a reference to the
  ///  <see cref="ConcurrentDictionary{Decimal, Boolean}"/> as
  ///  <see cref="T:ConcurrentDictionary<decimal, bool?>"/> that contains
  ///  the list of all PDF's that are currently opened and being displayed.
  /// </summary>
  private ConcurrentDictionary<decimal, bool?> openedPdfs = default!;

  Note: 
    The ConcurrentDictionary{Decimal, Boolean} will correctly produce a
    clickable link of ConcurrentDictionary{TKey, TValue} on hovering while
    T:ConcurrentDictionary<decimal, bool?> makes sure the reader gets
    information on what type TKey and TValue are.

Example # 2 (using "T")

  /// <summary>
  ///  This instance field holds a reference to the
  ///  <see cref="ConcurrentDictionary{TKey, TValue}"/> as
  ///  <see cref="T:ConcurrentDictionary<decimal, bool?>"/> that contains
  ///  the list of all PDF's that are currently opened and being displayed.
  /// </summary>
  private ConcurrentDictionary<decimal, bool?> openedPdfs = default!;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文