Хорошо, это то, что я придумал.
Я использую специальный тег 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>
Почему я хочу, чтобы этоway:
- И идентификатор свойства (экземпляр
DependencyProperty
), и свойство являются общедоступными и поэтому могут юридически использоваться для доступа к свойству.Так как у нас есть два API к одной и той же логической переменной. - Документация кода должна описывать то, чего еще нет.В этом контексте он должен описать значение свойства и его значение и как правильно его использовать.Поскольку оба, идентификатор свойства и свойство c #, ссылаются на одну и ту же логическую переменную, они имеют одинаковое значение.
- Пользователь может свободно выбирать один из двух способов доступа к логической переменной и не должен знать об этом.другого.И то, и другое должно быть задокументировано надлежащим образом.
- Комментарии к коду вставки копии так же плохи, как и код вставки копии.