方法可以被设置为静态的,但是应该这样做吗?

ReSharper喜欢在每个ASP中指出多个函数。NET页面,可以设置为静态。如果我把它们变成静态的,对我有帮助吗?我是否应该将它们设置为静态并将它们移动到实用程序类中?

77309 次浏览

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

您应该在给定的场景中使用最易读和最直观的方法。

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

如果函数在许多页面中共享,你也可以把它们放在一个基页类中,然后让所有使用该功能的asp.net页面继承它(函数也可以仍然是静态的)。

静态方法相对于实例方法
c#语言规范的静态成员和实例成员解释了这种差异。一般来说,静态方法可以提供比实例方法非常小的性能增强,但仅在某些极端情况下(有关详细信息,请参阅这个答案)

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

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

< p > 实用程序类
除非在设计中有意义,否则不应该将它们移到实用程序类中。如果静态方法与特定类型相关,例如ToRadians(double degrees)方法与表示角度的类相关,则该方法作为该类型的静态成员存在是有意义的(注意,为了演示,这是一个复杂的示例)

我相信这不会发生在您的情况下,但是在我不得不忍受维护的一些代码中,我看到了使用大量静态方法的“坏味道”。

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

然而,静态方法在排除域逻辑(实际上不依赖于对象实例的状态)时非常有用。它们可以使您的代码更具可读性。

只要确保你把它们放在正确的地方。静态方法是否侵入式地操纵其他对象的内部状态?能不能证明他们的行为属于其中一类呢?如果你没有正确地分离问题,你以后可能会头疼。

在类中将方法标记为static可以很明显地表明它不使用任何实例成员,这在浏览代码时很有帮助。

你不一定要把它移到另一个类中,除非它被另一个在概念上紧密关联的类所共享。

使方法静态意味着您可以从类外部调用该方法,而无需首先创建该类的实例。这在使用第三方供应商对象或附加组件时非常有用。想象一下,如果你在调用con. writeline()之前必须先创建一个Console对象“con”;

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

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

为了补充@Jason True的回答,重要的是要意识到,在方法上添加“static”并不能保证该方法将是“纯”的。对于声明它的类,它将是无状态的,但它可以很好地访问其他有状态的“静态”对象(应用程序配置等),这可能并不总是一件坏事,但我个人倾向于在可能的情况下更喜欢静态方法的原因之一是,如果它们是纯的,你可以孤立地测试和推理它们,而不必担心周围的状态。

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

另一方面,它可能导致类被大量实用方法所污染。通常,逻辑命名、文档和团队编码约定的一致应用程序可以缓解这种情况。

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

这是一个有趣的阅读:
http://thecuttingledge.com/?p=57 < / p > ReSharper实际上并不是建议你让你的方法是静态的。 你应该问问自己,为什么这个方法在那个类中,而不是在它的签名中出现的类之一…

但这是ReSharper documentaion说的: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static < / p >

只是我的一点钱:将所有共享的静态方法添加到实用程序类中,您就可以添加

using static className;

到您的using语句,这使得代码更快地输入和更容易阅读。例如,我在继承的一些代码中有大量所谓的“全局变量”。我没有在一个属于实例类的类中创建全局变量,而是将它们全部设置为全局类的静态属性。它完成了这项工作,虽然有些混乱,但我可以按名称引用属性,因为我已经引用了静态名称空间。

我不知道这是不是一个好的练习。关于c# 4/5,我有很多东西要学,还有很多遗留代码要重构,所以我只是想让Roselyn的技巧来指导我。

乔伊

我希望您已经理解了静态方法和实例方法之间的区别。而且,答案可以有长有短。其他人已经给出了很长的答案。

我的简短回答:是的,你可以将它们转换为ReSharper建议的静态方法。这样做没有坏处。相反,通过将方法设置为静态,实际上是在保护该方法,这样就不会不必要地将任何实例成员插入该方法。这样,你就可以实现一个面向对象的原则“__abc1”。

当ReSharper建议实例方法可以转换为静态方法时,它实际上是在告诉你,“为什么…这个方法在这个类中,但它实际上没有使用它的任何状态?所以,它给了你思考的食物。然后,由您来决定是否需要将该方法移动到静态实用程序类。根据SOLID原则,一个类应该只有一个核心职责。你可以用这种方式更好地清理你的类。有时,甚至在实例类中也需要一些helper方法。如果是这种情况,您可以将它们保存在#region helper中。