Language agnostic 如何避免文档注释中的冗余?

Language agnostic 如何避免文档注释中的冗余?,language-agnostic,documentation,coding-style,Language Agnostic,Documentation,Coding Style,我们刚刚开始使用StyleCop,我遇到的一件事是文档需求。我不想讨论这个工具的有用性,我只是想知道是否有人有任何指导方针或方法来考虑记录方法,从而使评论真正有用。我发现我的评论经常包含很多重复,只是为了满足StyleCop的要求,比如: /// <summary> /// Gets a dto of personal info. /// </summary> /// <param name="userId"> ///

我们刚刚开始使用StyleCop,我遇到的一件事是文档需求。我不想讨论这个工具的有用性,我只是想知道是否有人有任何指导方针或方法来考虑记录方法,从而使评论真正有用。我发现我的评论经常包含很多重复,只是为了满足StyleCop的要求,比如:

    /// <summary>
    /// Gets a dto of personal info.
    /// </summary>
    /// <param name="userId">
    /// The id of the user.
    /// </param>
    /// <returns>
    /// A dto containing personal info.
    /// </returns>
    public PersonalInfoDTO GetPersonalInfoDTO(int userId) {...}
//
///获取个人信息的dto。
/// 
/// 
///用户的id。
/// 
/// 
///包含个人信息的dto。
/// 
public PersonalInfoDTO GetPersonalInfoDTO(int userId){…}
是否有一种标准的方式来表达摘要和返回描述?您在参数描述中添加了什么?

“记录使注释实际有用的方法。我发现我的注释通常包含大量重复,只是为了满足StyleCop的要求。”

有用的和多余的没有任何关系

你的问题中没有定义“有用”。通常它的意思是“超过stylecop的要求”。如果你觉得有必要写更多的东西,那么,写更多的东西。Stylecop是最小值;你可以自由地超越这些最小值

在你的例子中,因为你写的是一个函数的摘要,这个函数做的很少。形式元素(参数和返回类型)和摘要相互重复是很常见的。我不确定这种重复是如何通过“有用”测试的。也许如果缺少什么,你可以加上它。请随意扩展和编写更多内容——没有什么可以阻止您编写超出最低限度的“有用”文档

冗余——虽然单调乏味——似乎并没有不起作用

记住,你的评论最终会创建索引和纯文本页面。正式结构化的部分对于索引和格式化至关重要

对于更复杂的类(和函数),总结是一个可以扩展细微差别的地方。例如“为什么?”或“什么时候可以使用,什么时候不能使用”,以及“其他约束条件”和“代码示例”之类更有用的东西


在任何时候,你都可以——也应该——写得超过最低限度。然而,对于琐碎的函数来说,写得超过最小值是没有意义的。

如果你被迫这么做,那么你可能不得不忍受一些重复,因为你已经使用了良好的自记录技术,比如智能命名

您可以在文档中包含的其他好处包括: 1) 格式化-是否对userID有任何限制,比如“所有低于500的用户都是管理员”或类似的限制?这些都是很好的评论与参数

2) 异常-如果您的方法要抛出或通过一个异常,请记录它,以便使用它的人知道如何处理它

3) 代码示例-显示如何使用您的方法

4) 特殊条件-返回对象是否处于任何奇数条件?如果找不到用户ID,您是否会传回null或空白/错误PersonalInfoDTO


当然,在简单的方法上,似乎有很多冗余信息,但更复杂的代码可以从完整的文档中受益匪浅。

强制执行此标准是有原因的,即使您觉得它有时是冗余信息。(即“用户ID->用户ID”)此注释还隐式包含该参数没有附加约束的信息

所以

。。。
/// 
///角度以度为单位。必须低于360且高于0。
///
...
如果您没有添加“必须低于x且高于y”,则表示对参数没有限制

类似地,对于标记。您可能认为返回值是不言自明的,但是标记是您应该告诉调用方这是否会在出错时返回null的地方。或者如果它返回一个值,即使有一个可能的响应列表


这类信息非常重要,stylecop只是强制您添加它

我倾向于非常怀疑那些强迫你在非常随意的地方添加评论的工具

别误会我的意思,我是评论的强烈拥护者。但是像你例子中的那些评论是纯粹的“噪音”:它们没有添加任何有用的东西,任何有意义的信息(如果有的话)都隐藏在绒毛后面

如果评论可以由自动工具生成。。。那么人类一开始就没必要写它们。如果出于其他原因(例如生成外部文档)必须这样做,那么您应该使用某种形式的自动脚本来生成这些文档,并将结果放在一个不显眼的位置


当然,关于这个函数的接口,您可以说很多有意义的事情。例如,参数的界限是什么

我试图通过在摘要中描述过程来避免重复。在参数中,您可以添加详细信息,例如有效范围,或者用户希望如何获取此信息。对于返回,我还列出了任何错误条件,例如:

/// <summary>
/// Gets a dto of personal info by querying the current list of users (or active directory or SQL)
/// </summary>
/// <param name="userId">
/// The id of the user. Must be greater than 0. The ID is stored in the application context or can be retrieved by a call to GetUserIdByName.
/// </param>
/// <returns>
/// A dto containing personal info. Returns null if the specified user information was not found.
/// </returns>
public PersonalInfoDTO GetPersonalInfoDTO(int userId) {...}
//
///通过查询当前用户列表(或active directory或SQL)获取个人信息的dto
/// 
/// 
///用户的id。必须大于0。该ID存储在应用程序上下文中,或者可以通过调用GetUserIdByName来检索。
/// 
/// 
///包含个人信息的dto。如果未找到指定的用户信息,则返回null。
/// 
public PersonalInfoDTO GetPersonalInfoDTO(int userId){…}
Jayrdub:

请记住,这些注释的目的是为代码创建文档。冗余是可以的,因为这些注释的不同部分可能在不同的场景中使用不同的方式——并不是所有的注释都可以在特定的场景中使用
/// <summary>
/// Gets a dto of personal info by querying the current list of users (or active directory or SQL)
/// </summary>
/// <param name="userId">
/// The id of the user. Must be greater than 0. The ID is stored in the application context or can be retrieved by a call to GetUserIdByName.
/// </param>
/// <returns>
/// A dto containing personal info. Returns null if the specified user information was not found.
/// </returns>
public PersonalInfoDTO GetPersonalInfoDTO(int userId) {...}
/// <summary>
/// Gets the user's personal information.
/// </summary>
/// <remarks>
/// We need this data transfer object in order to bridge Backend.SubsystemA
/// and Backend.SubsystemB. The standard <see cref="PersonalInfo"/> won't
/// work.
/// </remarks>
/// <param name="userId">Integer representing the user's ID.</param>
/// <returns>
/// <see cref="PersonalInfoDTO"/> representing the user, or <c>null</c>
/// if not available.
/// </returns>
public PersonalInfoDTO GetPersonalInfoDTO(int userId) {...}