Resharper喜欢指出每个asp.net页面可以静态化的多个函数.如果我让它们静止,对我有帮助吗?我应该将它们设置为静态并将它们移动到实用程序类吗?
在我看来,性能,命名空间污染等都是次要的.问自己什么是合乎逻辑的.该方法是在逻辑上对该类型的实例进行操作,还是与类型本身相关?如果是后者,请将其设为静态方法.如果它与不受您控制的类型相关,则仅将其移动到实用程序类中.
有时也有其逻辑上作用于一个实例,但不要发生在使用任何实例的状态的方法还没有.例如,如果你正在构建一个文件系统并且你已经获得了一个目录的概念,但是你还没有实现它,你可以编写一个返回文件系统对象类型的属性,它总是只是"file" - 但它在逻辑上与实例相关,因此应该是一个实例方法.如果要将方法设置为虚拟,这也很重要 - 您的特定实现可能不需要状态,但派生类可能不需要.(例如,询问集合是否为只读集合 - 您可能尚未实现该集合的只读形式,但它显然是集合本身的属性,而不是类型.)
静态方法与实例方法
10.2.5 C#语言规范的静态和实例成员解释了差异.通常,静态方法可以提供比实例方法更小的性能增强,但仅限于极端情况下(有关更多详细信息,请参阅此答案).
FxCop或代码分析中的规则CA1822规定:
"在[将成员标记为静态]之后,编译器将向这些成员发出非虚拟调用站点,这将阻止在运行时检查每个调用以确保当前对象指针为非null.这可以导致可测量的性能增益对于性能敏感的代码.在某些情况下,访问当前对象实例的失败代表了正确性问题."
实用
工具类除非在设计中有意义,否则不应将它们移动到实用工具类.如果静态方法涉及特定类型,就像ToRadians(double degrees)
方法涉及表示角度的类一样,那么该方法作为该类型的静态成员存在是有意义的(注意,这是用于演示目的的复杂示例).
将一个方法标记为static
一个类很明显它不使用任何实例成员,这有助于知道何时浏览代码.
你不一定要将它移动到另一个类,除非它意味着被另一个与概念相关联的类共享.
我确信这不会发生在你的情况下,但是我在一些代码中看到的一个"难闻的气味"我不得不通过维护使用大量静态方法而受到影响.
不幸的是,它们是假定特定应用程序状态的静态方法.(为什么我们每个应用程序只有一个用户!为什么不让User类在静态变量中跟踪它?)它们是访问全局变量的美化方式.他们也有静态构造函数(!),这几乎总是一个坏主意.(我知道有几个合理的例外).
但是,静态方法在分解出实际上并不依赖于对象实例状态的域逻辑时非常有用.它们可以使您的代码更具可读性.
确保你把它们放在正确的位置.静态方法是否会侵入性地操纵其他对象的内部状态?可以说一个好的案例,他们的行为属于这些类之一吗?如果你没有正确地分离问题,你可能会在以后遇到麻烦.
这很有趣:
http://thecuttingledge.com/?p=57
ReSharper实际上并不建议你让你的方法保持静态.你应该问问自己为什么那个方法在那个类中,而不是比如在其签名中出现的一个类...
但是这里是resharper documentaion所说的:http: //confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
只是为了添加@Jason True的答案,重要的是要认识到只在方法上加上'static'并不能保证该方法是'纯'的.对于声明它的类,它将是无状态的,但它可能会访问具有状态(应用程序配置等)的其他"静态"对象,这可能并不总是坏事,但其中一个原因是我个人倾向于喜欢静态方法,如果它们是纯粹的,你可以单独测试和推理它们,而不必担心周围的状态.
您应该在给定方案中执行最具可读性和直观性的操作.
性能参数不是一个好的,除非在最极端的情况下,因为实际发生的唯一事情是一个额外的参数(this
)被推入到堆栈中的实例方法.
对于类中的复杂逻辑,我发现私有静态方法在创建隔离逻辑时非常有用,其中实例输入在方法签名中明确定义,并且不会发生实例副作用.所有输出必须通过返回值或out/ref参数.将复杂的逻辑分解为无副作用的代码块可以提高代码的可读性和开发团队对它的信心.
另一方面,它可能导致被实用方法的扩散污染的类.像往常一样,团队编码约定的逻辑命名,文档和一致应用可以缓解这种情况.
ReSharper不检查逻辑.它仅检查方法是否使用实例成员.如果该方法是私有的并且仅由(可能只是一个)实例方法调用,则这是一个让它成为实例方法的标志.