代码之家  ›  专栏  ›  技术社区  ›  Stefan

依赖项属性的XML文档

  •  7
  • Stefan  · 技术社区  · 15 年前

    记录依赖属性的最佳方法是什么?

    我是否应该将XML文档放在字段上:

    /// <summary>Documentation goes here</summary>
    public static readonly DependencyProperty NameProperty = 
            DependencyProperty.Register(...)
    

    或在财产上:

    /// <summary>and/or here?</summary>
    public string Name{ get{...} set{...} }
    

    或者我真的需要记录(和维护)两者吗?

    2 回复  |  直到 15 年前
        1
  •  2
  •   Stefan    15 年前

    好吧,这就是我想出来的。

    我在依赖属性中使用了一个特殊的XML标记,它将被XSL转换替换。如果没有它也可以这样做,但是Visual Studio会发出警告,因为该字段似乎未经记录。

    /// <dpdoc />
    public static readonly DependencyProperty PositionProperty = 
        DependencyProperty.Register(...)
    

    C属性像往常一样记录在案,只需确保不要忘记值描述。

    /// <summary>Gets or sets the position of this element</summary>
    /// <value>Position (in pixel) relative to the parent's upper left corner.</value>
    /// <remarks><para>
    /// If either the <c>x</c> or <c>y</c> component is <c>+inf</c> this indicates...
    /// </para></remarks>
    public Point Position{ get{...} set{...} }
    

    Visual Studio在生成期间根据这些注释创建一个XML文件。通过一点XSL转换, dpdoc 节点替换为属性文档的修改版本。生成的XML文件与我们很好地记录了属性标识符的情况相同。它甚至包括一个简短的注释,即有一种访问变量的可选方法:

    /// <summary>Position (in pixel) relative to the parent's upper left corner.</summary>
    /// <remarks><para>
    /// If either the <c>x</c> or <c>y</c> component is <c>+inf</c> this indicates...
    /// <para>
    /// This dependency property can be accessed via the <see cref="Position"/> property.
    /// </para>
    /// </para></remarks>
    public static readonly DependencyProperty PositionProperty = 
        DependencyProperty.Register(...)
    

    这样,两个API都有适当的文档,我们不需要在代码中复制文档。XSL转换可以在构建后事件中完成,也可以集成到文档生成过程中。

    这是XSL:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="//dpdoc">
            <xsl:variable name="propertyName" select="concat('P:', substring(../@name,3,string-length(../@name)-10))" />
            <summary>
                <xsl:apply-templates select="//member[@name=$propertyName]/value/node()"/>
            </summary>
            <xsl:apply-templates select="//member[@name=$propertyName]/*[not(self::remarks)][not(self::summary)][not(self::value)]"/>
            <remarks>
                <xsl:apply-templates select="//member[@name=$propertyName]/remarks/node()"/>
                <para>
                    This dependency property can be accessed via the
                    <see>
                        <xsl:attribute name="cref"><xsl:value-of select="$propertyName"/></xsl:attribute>
                    </see>
                    property.
                </para>
            </remarks>
        </xsl:template>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    为什么我要这样做:

    • 属性标识符 DependencyProperty 实例)和该财产是公共的,因此可以合法地用于访问该财产。假设我们有两个API连接到同一个逻辑变量。
    • 代码文档应该描述还没有看到的内容。在这种情况下,它应该描述属性的含义及其值,以及如何正确地使用它。因为属性标识符和C属性都引用了相同的逻辑变量,所以它们具有相同的含义。
    • 用户可以自由选择访问逻辑变量的两种方法之一,而musn不知道另一种方法。如果两者都必须正确记录。
    • 复制粘贴代码注释和复制粘贴代码一样糟糕。
        2
  •  1
  •   Jeff Yates    15 年前

    你应该记录和维护这两者。一个是依赖属性,另一个是常规属性,恰好在访问该依赖属性时实现。它们不一样,需要单独的文档。