依赖属性的 XML 文档

发布于 2024-09-29 23:58:23 字数 398 浏览 10 评论 0原文

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

我应该将 xml 文档放在 field:

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

或 property: 上

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

,还是我真的需要记录(和维护)两者?

What is the best way to document a dependency property?

Should I put the xml documentation on the field:

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

or on the property:

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

or do I really need to document (and maintain) both?

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

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

发布评论

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

评论(2

Saygoodbye 2024-10-06 23:58:23

好吧,这就是我想出的。

我在依赖属性中使用特殊的 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# 属性都引用相同的逻辑变量,因此它们具有相同的含义。
  • 用户可以自由选择两种访问逻辑变量的方式之一,而不必知道另一种方式。两者都必须正确记录。
  • 复制粘贴代码注释和复制粘贴代码一样糟糕。

Ok, this is what I've come up with.

I use a special xml tag at the dependency properties that will be replaced by an xsl transformation. It would be possible to do it without it, but then Visual Studio issues a warning because the field appears undocumented.

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

The C# property is documented as usual, just make sure not to forget the value description.

/// <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 creates an xml file from those comments during building. With a little xsl transformation the dpdoc node is replaced by a modified version of the property documentation. The resulting xml file is the same as if we nicely documented the property identifier. It even includes a short note that there is an alternative way of accessing the variable:

/// <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(...)

That way, both API's have proper documentation and we don't need to duplicate the documentation in the code. The xsl transformation can be done in the post-build events or be integrated in the documentation generation process.

Here's the 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>

Why I want to have it that way:

  • Both the property identifier (the DependencyProperty instance) and the property, are public and can therefore legally be used to access the property. Thous we have two APIs to the same logical variable.
  • Code documentation should describe what is not already there to see. In this context it should describe the meaning of the property and its value and how to use it correctly. Since both, property identifier and the c# property, reference the same logical variable, they have the same meaning.
  • The user can freely choose one of the two ways to access the logical variable, and musn't be aware of the other. Thous both must be documented properly.
  • Copy-pasting code comments is just as bad as copy-pasting code.
无人问我粥可暖 2024-10-06 23:58:23

您应该记录并维护两者。一个是依赖属性,另一个是常规属性,恰好是通过访问该依赖属性来实现的。它们不是同一件事,需要单独的文档。

You should document and maintain both. One is the dependency property, the other is a regular property that just happens to be implemented as accessing that dependency property. They are not the same thing and require separate documentation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文