当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《方法可以做成静态,但应该吗?》经验,为你挑选了9个好方法。

Resharper喜欢指出每个asp.net页面可以静态化的多个函数.如果我让它们静止,对我有帮助吗?我应该将它们设置为静态并将它们移动到实用程序类吗?



1> Jon Skeet..:

在我看来,性能,命名空间污染等都是次要的.问自己什么是合乎逻辑的.该方法是在逻辑上对该类型的实例进行操作,还是与类型本身相关?如果是后者,请将其设为静态方法.如果它与不受您控制的类型相关,则仅将其移动到实用程序类中.

有时也有其逻辑上作用于一个实例,但不要发生在使用任何实例的状态的方法还没有.例如,如果你正在构建一个文件系统并且你已经获得了一个目录的概念,但是你还没有实现它,你可以编写一个返回文件系统对象类型的属性,它总是只是"file" - 但它在逻辑上与实例相关,因此应该是一个实例方法.如果要将方法设置为虚拟,这也很重要 - 您的特定实现可能不需要状态,但派生类可能不需要.(例如,询问集合是否为只读集合 - 您可能尚未实现该集合的只读形式,但它显然是集合本身的属性,而不是类型.)



2> Jeff Yates..:

静态方法与实例方法
10.2.5 C#语言规范的静态和实例成员解释了差异.通常,静态方法可以提供比实例方法更小的性能增强,但仅限于极端情况下(有关更多详细信息,请参阅此答案).

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

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

实用
工具类除非在设计中有意义,否则不应将它们移动到实用工具类.如果静态方法涉及特定类型,就像ToRadians(double degrees)方法涉及表示角度的类一样,那么该方法作为该类型的静态成员存在是有意义的(注意,这是用于演示目的的复杂示例).


我直接从FxCop 1.36剪切并粘贴它.如果FxCop错了,那就公平了.
@Maxim你的观点无效.我向你保证,9年前我没有得到很好的评价.我赞赏那些指出错误(或编辑纠正错误)的评论,但不要粗鲁,也不要对其他人提出不合理的期望.不要称之为"胡说八道"; 它意味着欺骗而不是诚实的善意错误或无知.这很粗鲁.我自愿在这里帮忙,在不尊重的时候感觉毫无意义.不要告诉我被冒犯了什么 - 这是我的选择,而不是你的选择.了解如何尊重和诚信地表达自己的观点.谢谢.
@Maxim不确定我欣赏"废话"声明; 接近陌生人的方式很粗鲁.但是,基本观点是有效的; 我已经更新了一些东西(它是在9年前,所以我不记得我原来的主张的基础).
>编译器会向这些成员发出非虚拟调用站点实际上就是"编译器可能会发出......".我记得一些关于使用callvirt的C#编译器而不是调用来解决一些潜在的bug.
@Maxim虽然委托不是存储在每个实例旁边,但是无状态类的每个实例确实占用了堆上的一些内存,这是无用的开销.通常,实例化服务并不是应​​用程序中的热门途径,但如果您的应用程序最终构建了大量这些对象,那么就会产生GC压力,只需使用静态方法就可以避免这种压力.OP最初声称,在极端情况下,静态方法比无状态实例提供了性能优势,具有适当的细微差别和有效性.

3> Mark Cidade..:

将一个方法标记为static一个类很明显它不使用任何实例成员,这有助于知道何时浏览代码.

你不一定要将它移动到另一个类,除非它意味着被另一个与概念相关联的类共享.



4> JasonTrue..:

我确信这不会发生在你的情况下,但是我在一些代码中看到的一个"难闻的气味"我不得不通过维护使用大量静态方法而受到影响.

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

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

确保你把它们放在正确的位置.静态方法是否会侵入性地操纵其他对象的内部状态?可以说一个好的案例,他们的行为属于这些类之一吗?如果你没有正确地分离问题,你可能会在以后遇到麻烦.


您的问题是静态字段/属性,而不是静态方法。

5> pajics..:

这很有趣:

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

ReSharper实际上并不建议你让你的方法保持静态.你应该问问自己为什么那个方法在那个类中,而不是比如在其签名中出现的一个类...

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


我认为这一点被低估了。该工具真正告诉您的是,该方法仅对某些其他类的成员起作用。如果是某种命令(或“用例”或“交互器”)对象,谁负责操作其他对象,那很好。但是,如果它只处理一个听起来很像[Feature Envy](http://wiki.c2.com/?FeatureEnvySmell)的其他类,则该类不起作用。

6> Benjol..:

只是为了添加@Jason True的答案,重要的是要认识到只在方法上加上'static'并不能保证该方法是'纯'的.对于声明它的类,它将是无状态的,但它可能会访问具有状态(应用程序配置等)的其他"静态"对象,这可能并不总是坏事,但其中一个原因是我个人倾向于喜欢静态方法,如果它们是纯粹的,你可以单独测试和推理它们,而不必担心周围的状态.



7> Eric Schoono..:

您应该在给定方案中执行最具可读性和直观性的操作.

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



8> G-Wiz..:

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

另一方面,它可能导致被实用方法的扩散污染的类.像往常一样,团队编码约定的逻辑命名,文档和一致应用可以缓解这种情况.



9> brgerner..:

ReSharper不检查逻辑.它仅检查方法是否使用实例成员.如果该方法是私有的并且仅由(可能只是一个)实例方法调用,则这是一个让它成为实例方法的标志.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有