好吧,这就是我想出来的。
我在依赖属性中使用了一个特殊的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不知道另一种方法。如果两者都必须正确记录。
-
复制粘贴代码注释和复制粘贴代码一样糟糕。