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

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

如果我要在某个地方编写xml文档,我该如何引用这个奇特的类呢?我怎么能引用一个幻想类<字符串>?方法呢?

例如,在一个不同的类中,我想让用户知道我将返回一个FancyClass<int>的实例。我怎么能做一个see cref的东西?


当前回答

引用方法:

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

其他回答

到目前为止,没有一个答案完全适合我。ReSharper不会将see标签转换为Ctrl+可点击的链接(例如),除非它完全解析。

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

<参见 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)

或者“有两个类型参数的类,它有一个有三个类型参数的方法,其中方法参数是ClassType1, ClassType2, MethodType1, MethodType2, MethodType3”


作为一个额外的说明,我没有发现这个记录在任何地方,我不是一个天才,编译器告诉我这一切。你所要做的就是创建一个测试项目,启用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->成员元素中的链接:

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

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

TL; diana:

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

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

“《FancyClass<T>》怎么样?FancyMethod < K > (T值)?”

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

“我如何引用一个幻想类<字符串>?”

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

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

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 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文档注释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);
    }
}
/// <see cref="FancyClass&lt;T>.FancyMethod&lt;K>(T)"/> for more information.

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

我尝试了堆栈溢出的一切,以获得在几种情况下工作的结果。这里有一个对我有用的解决办法。(这对其他人来说是主观的。)

产生可点击的链接。 将鼠标悬停在标识符上是可行的。 正确生成.xml文件。 在智能感知中不产生错误。 适用于可空的泛型类型参数。 工作在Resharper和它的内置XML文档窗口(Resharper ->编辑->显示快速文档) 工作在XAM文档预览的Atomineer Pro Documentaion Visual Studio扩展。 使用泛型类型的泛型类型。

示例# 1

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

从Lasse和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.

也会正确地提供工具提示,而他们的版本用花括号呈现。