方法可以做成静态的,但应该吗?

Resharper喜欢指出每个asp.net页面可以变成静态的多个函数。 如果我把它们变成静态的,它能帮助我吗? 我应该让他们静态和移动他们到公用事业类?

静态方法与实例方法
10.2.5 C#语言规范的静态和实例成员解释了不同之处。 一般来说,静态方法可以比实例方法提供一个非常小的性能增强,但仅在某些极端情况下(请参阅此答案以获取更多详细信息)。

FxCop或代码分析中的规则CA1822指出:

“[将成员标记为静态]之后,编译器将向这些成员发出非虚拟调用站点,这将阻止在运行时检查每个调用的确保当前对象指针非空的调用,从而可以获得可衡量的性能增益对性能敏感的代码,在某些情况下,访问当前对象实例的失败代表了正确性问题。“

实用程序类
除非在devise中有意义,否则不应该将它们移动到实用类。 如果静态方法涉及特定的types,就像ToRadians(double degrees)方法涉及到一个表示angular度的类,那么这个方法就可以作为该types的静态成员存在是有意义的(注意,这是一个复杂的例子示范目的)。

在我看来,性能,命名空间污染等都是次要的。 问自己什么是合乎逻辑的。 该方法逻辑上是在types的一个实例上运行,还是与types本身有关? 如果是后者,则将其作为静态方法。 如果它与一个不受你控制的types相关,那么只把它移到一个实用类中。

有时候,有些方法在逻辑上作用于一个实例,但不会碰巧使用任何实例的状态。 例如,如果你正在构build一个文件系统,并且你有一个目录的概念,但是你还没有实现它,你可以编写一个返回文件系统对象的属性,它总是只是“文件” – 但它在逻辑上与实例有关,所以应该是一个实例方法。 如果你想让这个方法变成虚拟的,这也是很重要的 – 你的特定实现可能不需要任何状态,但派生类可能不需要。 (例如,询问一个集合是否是只读的 – 您可能还没有实现该集合的只读表单,但它显然是集合本身的属性,而不是types。)

在类中标记一个static方法很明显,它不会使用任何实例成员,这些成员可以帮助您了解何时浏览代码。 你不一定要把它移到另一个类,除非它是由另一个同样紧密相关的概念明智地分享的。

我敢肯定这种情况不会发生在你的情况中,但是我在维护中遇到的一些代码中看到的一种“难闻的气味”使用了大量的静态方法。

不幸的是,它们是假定特定应用程序状态的静态方法。 (为什么肯定,我们只有每个应用程序有一个用户!为什么不让User类跟踪静态variables?)他们是访问全局variables的光荣方式。 他们也有静态构造函数(!),这几乎总是一个坏主意。 (我知道有一些合理的例外)。

但是,静态方法在将实际上并不依赖于对象实例状态的域逻辑分解出来时非常有用。 他们可以使你的代码更具可读性。

只要确保你把他们放在正确的地方。 静态方法是否侵入性地操纵其他对象的内部状态? 他们的行为是否属于这些类别中的一个,能否成功呢? 如果你没有把问题分开,那么以后你可能会头疼。

只要添加@Jason True的答案 ,重要的是要认识到,只是将“静态”放在方法上并不能保证该方法将是“纯”的。 关于声明它的类将是无状态的,但它可以很好地访问其他具有状态(应用程序configuration等)的“静态”对象,但这并不总是一件坏事,而是其中一个原因我个人倾向于倾向于select静态方法,如果它们是纯粹的,那么可以孤立地testing和推理它们,而不必担心周围的状态。

对于类中的复杂逻辑,我发现私有静态方法在创build孤立的逻辑时很有用,其中实例input在方法签名中明确定义,并且不会出现实例副作用。 所有输出必须通过返回值或输出/参考参数。 将复杂逻辑分解为无副作用的代码块可以提高代码的可读性和开发团队的信心。

另一方面也可能导致一种被效用方法泛滥的阶级所污染。 像往常一样,逻辑命名,文档和团队编码惯例的一致应用可以缓解这一点。

这是有趣的读:

http://thecuttingledge.com/?p=57

ReSharper实际上并不build议你让你的方法是静态的。 你应该问自己,为什么这个方法是在这个类中,而不是在签名中出现的类之一。

但这里是resharper文档说: http : //confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static

ReSharper不检查逻辑。 它只检查该方法是否使用实例成员。 如果该方法是私有的,只能通过(也许只有一个)实例方法调用,这是一个让它成为实例方法的标志。

您应该在给定的情况下做最可读性和直观性的事情。

性能参数是不是一个好的,除非在最极端的情况下,因为唯一实际发生的是一个额外的参数( this )被推入到堆栈中,例如方法。

它有助于控制命名空间的污染。

如果这些函数是在多个页面之间共享的,你也可以把它们放在一个基本的页面类中,然后使用这个function的所有asp.net页面都inheritance它(并且函数也可以是静态的)。

使方法成为静态的方法意味着您可以在不需要先创build该类的实例的情况下从类外部调用该方法。 在使用第三方供应商对象或附件时这很有帮助。 想象一下,如果你在调用con.Writeline()之前必须先创build一个控制台对象“con”

只是我的tuppence:将所有共享的静态方法添加到工具类允许您添加

 using static className; 

到您使用的语句,这使得代码更快,更容易阅读。 例如,在我inheritance的一些代码中,我有大量的被称为“全局variables”的东西。 我不是在作为实例类的类中创build全局variables,而是将它们全部设置为全局类的静态属性。 它做这个工作,如果混乱,我可以通过名称引用属性,因为我已经引用了静态名称空间。

我不知道这是否是好的做法。 我有很多东西要学习C#4/5和那么多的遗留代码来重构,我只是想让Roselyn的技巧指导我。

乔伊