ReSharper喜欢指出每个ASP.NET页面中可以变成静态的多个函数。 如果我将它们变成静态的,这会对我有所帮助吗?我应该将它们变成静态并移动到实用程序类中吗?
ReSharper喜欢指出每个ASP.NET页面中可以变成静态的多个函数。 如果我将它们变成静态的,这会对我有所帮助吗?我应该将它们变成静态并移动到实用程序类中吗?
在我看来,性能、命名空间污染等都是次要的。问问自己,这个方法是否在逻辑上操作类型的实例,还是与类型本身相关?如果是后者,请将其变为静态方法。只有当它与您无法控制的类型相关时,才将其移动到实用类中。
有时候可能会有一个逻辑上作用于实例的方法,但暂时不使用任何实例状态。例如,如果您正在构建文件系统并且已经有了目录的概念,但尚未实现它,您可以编写一个返回文件系统对象类型的属性,并且它始终只是“文件”-但它与实例逻辑相关,因此应该是实例方法。如果您想将方法设置为虚拟,则这也很重要-您特定的实现可能不需要状态,但派生类可能需要。(例如,询问集合是否为只读-您可能尚未实现该集合的只读形式,但它显然是集合本身的属性,而不是类型的属性。)
静态方法与实例方法
C#语言规范中的静态成员和实例成员解释了它们之间的区别。通常情况下,静态方法可以在某些极端情况下提供非常小的性能优化(有关详细信息,请参见这个答案)。
FxCop或代码分析中的规则CA1822说明:
“标记成员为静态之后,编译器将向这些成员发出非虚拟调用站点,这将防止每次调用时检查确保当前对象指针为非空。对于性能敏感的代码,这可能会导致可衡量的性能提升。在某些情况下,无法访问当前对象实例表示一个正确性问题。”
工具类
除非符合设计要求,否则不应将它们移动到工具类中。如果静态方法与特定类型相关联,例如ToRadians(double degrees)
方法与表示角度的类相关联,则该方法作为该类型的静态成员存在是有意义的(请注意,这是一个为了演示目的而编造的复杂示例)。
在类中将一个方法标记为static
能够明确地表明它不使用任何实例成员,在浏览代码时这一点可能很有帮助。
除非这个方法旨在与另一个与其概念相关联的类共享,否则您不一定需要将其移动到另一个类中。
我相信在您的情况下不会出现这种情况,但是在我维护的一些代码中,我看到了一些“坏味道”,其中使用了大量的静态方法。
不幸的是,它们是假设特定应用程序状态的静态方法。 (为什么不呢?我们只有一个用户每个应用程序!为什么不让User类在静态变量中跟踪它?)它们实际上是访问全局变量的高级方式。 它们还包含静态构造函数(!),这几乎总是一个坏主意。(我知道有一些合理的例外情况)。
然而,当静态方法因素化出不实际依赖于对象实例状态的领域逻辑时,它们非常有用。 它们可以使您的代码更易读。
只要确保将它们放在正确的位置。 静态方法是否会强制性地操作其他对象的内部状态? 是否能够充分证明它们的行为属于其中一个类? 如果您没有正确地分离关注点,您可能会在以后遇到麻烦。
这是一篇有趣的阅读:
http://thecuttingledge.com/?p=57
ReSharper实际上并没有建议您将方法设置为静态。 您应该问自己为什么该方法在该类中而不是在其签名中显示的某个类中...
但是这里是ReSharper文档所说的: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
补充一下@Jason True的答案,请注意仅仅在方法上加上“static”并不能保证方法是“纯”的。关于声明方法的类,它将不具备状态,但它可能会访问其他有状态的“静态”对象(如应用程序配置等)。这可能并不总是坏事,但我个人倾向于在可以使用静态方法时使用它们的原因之一是,如果它们是纯的,就可以在不必担心周围状态的情况下测试和理解它们。
在特定情况下,您应该做最易读和直观的事情。
性能论点除了在极端情况下外并不是一个好的论点,因为实际发生的唯一事情就是将一个额外的参数 (this
) 推送到实例方法的堆栈上。
ReSharper并不会检查逻辑。它只会检查方法是否使用实例成员。 如果该方法是私有的,且仅被(可能只有一个)实例方法调用,则这表明应将其作为实例方法。
我希望你已经明白了静态方法和实例方法之间的区别。同时,这个问题有长答案和短答案。其他人已经提供了长答案。
我的短答案:是的,你可以像ReSharper建议的那样将它们转换为静态方法。这样做没有害处。相反,通过使该方法成为静态方法,您实际上正在保护该方法,以便您不会无意中将任何实例成员放入该方法中。通过这种方式,您可以实现面向对象编程原则“最小化类和成员的可访问性”。
当ReSharper建议将实例方法转换为静态方法时,它实际上是在告诉您:“为什么这个方法坐在这个类中,但实际上却没有使用它的任何状态?”因此,它给您提供了思考的食物。然后,你可以意识到将该方法移动到静态实用程序类中的需要与否。根据SOLID原则,一个类应该只有一个核心职责。因此,您可以通过这种方式更好地清理您的类。有时,即使在您的实例类中,您也需要一些辅助方法。如果是这样的情况,您可以将它们保留在一个#region helper中。