为啥 StyleCop 建议在方法或属性调用前加上“this”?
Posted
技术标签:
【中文标题】为啥 StyleCop 建议在方法或属性调用前加上“this”?【英文标题】:Why does StyleCop recommend prefixing method or property calls with "this"?为什么 StyleCop 建议在方法或属性调用前加上“this”? 【发布时间】:2010-12-06 11:02:42 【问题描述】:我一直在尝试遵循 StyleCop 的项目指南,看看最终生成的代码是否更好。大多数规则都是合理的,或者是关于编码标准的意见问题,但有一条规则让我感到困惑,因为我没有看到其他人推荐它,而且我没有看到它有明显的好处:
SA1101:对 method or property name 的调用必须以“this.”开头。前缀表示该项目是该类的成员。
不利的一面是,这样的代码显然更冗长,那么遵循该规则有什么好处?这里有人遵守这条规则吗?
【问题讨论】:
请记住,StyleCop 旨在根据您的需要进行配置,默认设置可能不是最佳的。也不是所有的 StyleCop 规则都同样合理,事实上,我记得有一些是完全矛盾的,并且在两者都启用时不可能满足。如果您已经拥有适合您的编码风格(例如,带有_
的前缀字段似乎很流行),请坚持下去,并相应地更改 StyleCop 设置。
默认设置代表一个标准,因此如果您的目标是让代码符合由团队外部机构创建的标准,则不要自定义规则。
@Pavel:我假设 StyleCop 附带 Microsoft 遵循的默认规则,我相信这些规则是有道理的。在更改默认值之前,我想了解为什么要这样设置!
@Mathias - 一些规则,比如在哪里放置 using
声明,甚至不满足类模板的要求。我不确定所有人都是理智的。
@Mathias:如果我回想 StyleCop 的历史,它最初并未在 Microsoft 范围内使用。我不会假设 StyleCop 规则是整个 Microsoft 使用的规则。尤其不是“这个”。规则。
【参考方案1】:
除非我处于您需要的场景中,否则我不会真正遵循此指导:
存在实际歧义 - 主要这会影响构造函数 (this.name = name;
) 或 Equals
(return this.id == other.id;
) 之类的东西
您想传递对当前实例的引用
您想在当前实例上调用扩展方法
除此之外,我认为这是杂乱无章的。所以我关闭了规则。
【讨论】:
这绝对是正确的回应。在你的代码中使用“this”是愚蠢的,而且从来没有在任何地方教授过。【参考方案2】:可以让代码一目了然。当您使用this
时,更容易:
【讨论】:
同意类字段与局部变量。类字段的 _ 或 m_ 表示法对我来说似乎很古老,而这条规则是一种合理的方式来替换它,同时保持可读性。 您可以通过在成员变量上使用唯一的词缀来完成完全相同的事情(例如,m_name
与 name
)并且在本地和参数变量上不使用任何词缀。不过,这是一个品味问题。
@Loadmaster - 我还要补充一点,通过使用诸如下划线之类的词缀/前缀,它通过名称强制使用,而使用“this”关键字,您必须依靠 StyleCop 之类的工具来强制使用。
如果你使用this
来区分成员那么你基本上是在使用命名对流,所以它并不比前缀_
或m_
好。事实上,更糟糕的是使用this
需要更多字符。
Visual Studio 建议删除 stylecop 建议我添加的“this”。他们不能下定决心吗?【参考方案3】:
我觉得这篇文章解释了一点
http://blogs.msdn.microsoft.com/sourceanalysis/archive/2008/05/25/a-difference-of-style.aspx
...Microsoft 的一位才华横溢的年轻开发人员(好吧,是我)决定自己编写一个小工具,该工具可以检测其团队中使用的 C# 风格的差异。 StyleCop 诞生了。在接下来的几年里,我们收集了可以从 Microsoft 的各个团队中找到的所有 C# 样式指南,并挑选出这些样式共有的所有最佳实践。这些形成了第一套 StyleCop 规则。这项工作产生的最早规则之一是使用 this 前缀来调用类成员,并从字段名称中删除任何下划线前缀。 C# 风格已正式脱离其旧的 C++ 部落。
【讨论】:
谢谢,很高兴知道内幕! 感谢您的链接。它告诉我为什么 StyleCop 规则在很大程度上是废话——它们是来自分散团队的一堆规则,而不是一套经过深思熟虑的单一规则,经过研究确定它们实际上是最适合各种能力。 无论如何,在 2019 年,stylecop.analyzers 似乎有一些非常强大的规则,我保留了大部分启用;只有少数这样和禁止#region 确实值得怀疑。希望更好地定制和覆盖其他一些东西,例如行长作为规则集的一部分,但在大多数情况下,它很棒。我的意思是,我在这里只是因为我查看每条规则的优点。 2020 年 11 月 4 日,链接已损坏。【参考方案4】:this.This
this.Does
this.Not
this.Add
this.Clarity
this.Nor
this.Does
this.This
this.Add
this.Maintainability
this.To
this.Code
“this.”的使用,当过度使用或强制样式要求时,只不过是在有
一旦您开始输入,Intellisence 就会列出您输入范围内的可用内容,“this”。没有必要暴露类成员,除非你完全不知道你正在为什么编码,否则你应该能够轻松找到你需要的项目。
即使您完全一无所知,也请使用“this”。提示可用的内容,但不要将其留在代码中。还有许多像 Resharper 这样的附加组件,有助于使范围更加清晰,并更有效地公开对象的内容。最好学习如何使用提供给您的工具,然后养成被大量同事讨厌的坏习惯。
任何天生不了解静态、本地、类或全局内容范围的开发人员不应依赖“提示”来指示范围。 “这。”比匈牙利表示法更糟糕,因为至少匈牙利表示法提供了关于变量引用的类型的想法并提供了一些好处。我宁愿看到用于表示类字段成员的“_”或“m”,然后看到“this”。无处不在。
我从来没有遇到过问题,也没有遇到过与代码范围反复斗争或编写的代码因为不使用“this”而总是有问题的开发人员的问题。明确地。 “这个”是一种无端的恐惧。防止未来的代码错误,并且通常是在重视无知的情况下使用的论据。
编码员随着经验而成长,“这个”。就像要求某人成年后在他们的自行车上安装辅助轮,因为这是他们学习如何骑自行车时首先必须使用的。成年人骑自行车的次数可能有千分之一从自行车上摔下来,但这不是强迫他们使用辅助轮的理由。
“这个。”应该从 C# 的语言定义中被禁止,不幸的是只有一个原因使用它,那就是解决歧义,这也可以通过更好的代码实践来轻松解决。
【讨论】:
说得好。由于缺少“this”,我想不出我们在过去几年中遇到的任何错误。与辅助轮很好的比较:) 说得好。就我而言,不必要的混乱。【参考方案5】:请注意,编译器并不关心您是否为引用添加前缀this
(除非与局部变量和字段发生名称冲突,或者您想在当前实例上调用扩展方法。)
这取决于你的风格。就我个人而言,我从代码中删除了this.
,因为我认为它会降低信噪比。
仅仅因为微软内部使用这种风格并不意味着你必须这样做。 StyleCop 似乎是一个公开的 MS 内部工具。我完全赞成遵守 Microsoft 围绕公共事务的约定,例如:
类型名称采用 PascalCase 格式 参数名称采用驼峰命名法 接口应以字母 I 为前缀 对枚举使用单数名称,除非它们是 [标志]...但是在您的代码的私有领域中发生的事情是私有的。做任何你的团队同意的事情。
一致性也很重要。它可以减少阅读代码时的认知负担,尤其是在代码风格符合您预期的情况下。但即使在处理外国编码风格时,如果它是一致的,那么很快就会习惯它。使用 ReSharper 和 StyleCop 等工具确保在您认为重要的地方保持一致性。
使用 .NET Reflector 表明微软在遵守 BCL 中的 StyleCop 编码标准方面并不擅长。
【讨论】:
.NET Reflector 不会向您显示所编写的源代码,例如它的输出很少告诉你代码的风格,毕竟它是一个反编译器。 @Ian - 你说得对,this
被编译掉了,但是其他的东西,比如带有下划线前缀的字段仍然存在。如果您查看 MS 现在允许您下载的源代码(以及 ReSharper 等工具导航到的源代码),您也会在 BCL 中看到不同的编码风格。【参考方案6】:
使用this
的几个基本原因(巧合的是,我总是在类值前面加上它们所属的类的名称——即使在类本身中也是如此)。
1) 清晰度。你马上就知道你在类定义中声明了哪些变量,哪些声明为局部变量、参数等等。两年后,您将不会知道这一点,您将进行一次奇妙的重新发现之旅,如果您事先明确说明父母,这绝对没有意义,也不需要。处理您的代码的其他人从一开始就不知道,因此立即受益。
2) 智能感知。如果你输入“这个”。您可以在帮助中获得所有特定于实例的成员和属性。它使查找内容变得更加容易,尤其是在您维护别人的代码或几年未查看的代码时。它还可以帮助您避免因对在何处以及如何声明哪些变量和方法的误解而导致的错误。它可以帮助您发现在编译器阻塞您的代码之前不会显示的错误。
3) 当然,您可以通过使用前缀和其他技术来达到相同的效果,但这引出了一个问题,即当语言中内置了一种机制来处理问题时,为什么要发明一种机制来处理问题IDE支持吗?如果您触摸打字,即使是部分触摸,它最终也会降低您的错误率,因为不会强迫您将手指从初始位置移开以到达下划线键。
我看到很多年轻的程序员通过不输入一两个字符来节省大量时间。你的大部分时间都花在调试上,而不是编码上。不要太担心你的打字速度。更担心你能多快理解代码中发生了什么。如果您总共节省了 5 分钟的编码时间并赢得了多花 10 分钟的调试时间,那么无论您看起来有多快,您都会放慢自己的速度。
【讨论】:
你的最后一段基本上与你的第三点相矛盾。任何一个接触式打字员,并且从起始位置移动到下划线键的任何人都是......不是一个接触式打字员。 糟糕,错字。 “有 to 搬出...” 5 分钟后我无法编辑我的评论。【参考方案7】:我确实遵循它,因为我认为第一眼就能区分对静态成员和实例成员的访问非常方便。
当然,我必须在我的构造函数中使用它,因为我通常给构造函数参数赋予与为其赋值的字段相同的名称。所以我需要“this”来访问这些字段。
【讨论】:
【参考方案8】:此外,可以在函数中重复变量名,因此使用“this”可以使其更清晰。
class foo
private string aString;
public void SetString(string aString)
//this.aString refers to the class field
//aString refers to the method parameter
this.aString = aString;
【讨论】:
我经常在构造函数中看到这种做法,其中很多时候参数与添加“this”的各种私有字段和/或属性的名称相匹配。前缀有助于澄清代码,并在某些情况下避免名称冲突。【参考方案9】:我关注它主要是出于智能感知的原因。输入this.
并获得属性、方法等的简洁列表真是太好了。
【讨论】:
很好,但是一旦您完成了获取列表,this.
就不再具有任何价值。考虑一下:如果您可以键入一个与键入“this.
”相同的 IntelliSense 列表的击键,那么几乎不需要键入“'`this.'”。
我以前听过这个特别的借口,打这个。因为智能对我来说只是有点懒惰的味道。正如前面的评论指出的那样,不需要。此外,还有其他调用智能感知的方法。
出于同样的原因,我曾经输入 '.'在 Java 代码中,因为如果我没记错的话,像 JBuilder 这样的工具会选择它并提供智能感知。所以我认为在 Jave 中可以完全使用关键字“this”。以上是关于为啥 StyleCop 建议在方法或属性调用前加上“this”?的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 中签入之前构建解决方案的规则
StyleCop SA1124 DoNotUseRegions 是不是合理? [关闭]