如何在 C# 中评论/记录覆盖?

Posted

技术标签:

【中文标题】如何在 C# 中评论/记录覆盖?【英文标题】:How to comment/document an override in C#? 【发布时间】:2012-04-12 12:17:25 【问题描述】:

有时我会覆盖基类中的方法。有时我什至用一个空方法覆盖它们,因为我想要的是防止这种行为。

过去我会写这样的东西来显示绕过基本方法的意图

protected override void OnMouseUp(MouseEventArgs e)

    // base.OnMouseUp(e);

(我知道注释的代码行是一件坏事。我使用来做)

但我想做得更好:

我如何记录覆盖的意图?具体来说: 我在覆盖的 XML 中写什么 (<summary>?) 文档?

【问题讨论】:

en.wikipedia.org/wiki/Liskov_substitution_principle @Eva 我不确定你的意思。通过快速阅读这篇文章,我认为您是在说我不应该阻止基类行为? Here's 一个更好地解释它的 SO 问题。基本上你的子类不应该违反你的超类的不变量。您的子类应该添加功能,而不是更改或删除功能。通常,如果您的子类违反了 LSP,您可能正在查看组合情况。 @Eva 我明白了。如果我没记错的话,我使用它的时间是修改绘图行为和类似的东西;没有“副作用”。如果一个方法“没有副作用”,从某种意义上说,这些对代码来说是无形的,那么修改基类的行为是可以的,对吧? 不是修改状态。它是关于能够在所有实例中使用子类作为超类的替代品(或替代品)。在我发布的链接中,有方形和矩形的示例。您可以在没有副作用的情况下实现 Rectangle 的 Square 子类(在第二个链接的答案之一中有一个示例),但它仍然违反 LSP,因为 Rectangle 的不变量之一是当您更改宽度时,高度应该即使宽度和高度不同也不会改变。在第二个链接中有更好的解释。 【参考方案1】:

在我看来,注释掉基类调用与明确意图完全相反。人们会想知道为什么注释行仍然存在,以及它是否仍然有用,因为您没有删除它。所以我会删除注释掉的行。

您可以像任何其他方法一样记录覆盖,并在文档中指定您将方法留空的确切原因。您也可以将原因作为注释写入方法主体,我想这是一个偏好问题。

我认为这取决于此信息是否仅对维护代码的开发人员重要,或者对代码的用户(例如您的库的用户)也很重要。对于通常仅由操作系统调用的事件(例如在您的示例中),将它放在摘要标签中并不是必需的。

不过,如果您需要重写方法以禁用基类的行为,也许您应该重新考虑您设计的那部分。这种行为对我来说似乎有点不直观。

【讨论】:

我同意注释掉的代码行看起来确实很难看。我这样做只是因为它是个人代码并且我没有打扰,但现在我希望任何其他开发人员知道它为什么被覆盖。您是否建议我在 <summary> 标签中说明为什么它被覆盖? 我只是想了一遍,我认为这取决于方法。请参阅我的更新答案。 我不知道是不是只有我,但我从来没有重写我自己的类的方法,并且认为它只对不同意原始开发人员的代码用户有用(重写在我看来,你自己的东西意味着设计有问题)。我刚刚接受了另一个答案,但是 +1 因为您的编辑提出了一个需要考虑的重要问题。【参考方案2】:

对于文档,我会使用 built-in documentation tags:

/// <summary>Exiting drag mode on mouse up</summary>
protected override void OnMouseUp(MouseEventArgs e)

    ...

为了澄清意图,我只想发表评论

protected override void OnMouseUp(MouseEventArgs e)

    // not calling the base implementation
    ...

线

// base.OnMouseUp(e);

给人的印象是调用被暂时注释掉了(也许有人忘记恢复它)

【讨论】:

是的,我同意注释掉代码是不好的,这就是为什么我想要更好的东西。但是,XML 文档不应该声明它被继承以取消或改变其行为吗? @Camilo:好吧,这取决于。如果您认为您班级的用户 了解这些细节是好的/有趣/重要的,您可以将其放入文档中。如果此信息仅对您班级的开发人员感兴趣,请将其作为注释留在方法中。【参考方案3】:

类似的评论

// This method is intentionally blank because 
// we do not want the base class functionality

好很多
// base.SomeMethod();

第一条评论清楚地说明了你为什么要这样做,下一个出现的开发人员不必怀疑对基本方法的调用是否被意外注释掉了。

如果您可以控制基类,最好删除该方法并使类更抽象。然后,您可以选择仅在需要的子类中实现该功能。

【讨论】:

我打算在方法体上这样做。但是 XML 文档呢? 您是否想在 XML 文档中重申这一点取决于您。如果您认为有必要,您可以再次解释为什么要覆盖基类。一般来说,我认为一个名为“OnMouseUp”的方法是不言自明的,不需要太多的标题文档。这不是一成不变的,但对我来说,XML cmets 通常会告诉我“我在做什么”,而方法中的 cmets 会告诉我“为什么”我在做什么。 谢谢,这让人放心。作为第一个评论如何处理 XML cmets 的人,您的回答被接受了。

以上是关于如何在 C# 中评论/记录覆盖?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中排除方法以进行 sonarqube 代码覆盖

如何在 C# 中覆盖默认值(T)? [复制]

如何在 WPF C# 中覆盖(使用)BitmapFrame.Thumbnail 属性?

返回流C#时如何覆盖流关闭

如何实现基类的虚方法,并在c#中的覆盖方法中获取基方法实现[重复]

如何在 C# 中执行 DragAcceptFiles?