2

我使用 Developer Express 的 CodeRush 产品,它有一个名为 Code Issues 的功能,它会提出优化代码的建议。我注意到,如果您有一个具有参数的方法,它总是建议将此方法设为静态。本着尝试编写最好的代码并进行优化的精神,我认为这是 DevExpress 试图帮助我们做的事情,我听到了关于将方法设为静态是否真的明智的不同意见。

你对什么时候方法应该是静态的有什么看法?这样做有什么好处吗?影响?我看不出它有什么问题,因为它需要参数来运行该方法,因此这不是跨多个用户/使用的问题。

是好是坏?

谢谢。

4

5 回答 5

6

方法是否有参数与它无关。唯一的考虑是该方法是否尝试访问该类的任何非静态(即基于实例的)成员,或者该类中的其他静态成员是否调用它......

例如

 private static int Add(int a, int b) 
 { return a + b; }

可以是静态的 - 它不访问其容器类的任何实例成员,即使它有参数

但是在下面的类中,PrintHello()不能声明为静态,因为它访问基于实例的字段useCount,即使它没有参数。

public class myClass
{
    private int useCount = 0;

    private void PrintHello()
    { 
        useCount = useCount + 1;
        Console.Write("Hello");
    }
}
于 2011-11-11T15:28:25.097 回答
2

我通常不使用静态方法,因为它们很难与单元测试和依赖注入一起使用。(我知道typemock)。只有当方法被严格包含时,我才会考虑使用静态方法。

于 2011-11-11T15:34:12.393 回答
2

正如其他人所指出的,参数的存在不是考虑因素。当方法不访问任何实例成员时,会出现提示。

这什么时候有用?

当候选方法不需要状态来执行其功能时,不应要求此函数的调用者拥有或创建父类的实例。

通过删除此要求,调用代码将显示错误(或在某些语言中为警告),表明所讨论的方法“无法通过实例引用访问”,而需要类型引用。

当调用语句被重写以使用类型引用时,可能会发现不需要类型的原始实例,并且可以进一步重构代码以消除相同的创建。

消除这种实例类型将节省 cpu 和内存。

调用方法(或它自己的调用者)可能更容易阅读,因为所讨论的方法不需要实例化代码。

此外,如果缺少实例化代码,这将增加一个或多个方法的可读性。

例如 System.Math 类是静态的,因此填充了静态函数。如果必须在执行之前实例化数学类的实例,则为这些函数调用代码的可读性会降低。

于 2011-11-14T08:08:31.380 回答
1

就个人而言,我对这个问题有两种看法。

一方面,有人可能会争辩说该方法应该是静态的,因为它不访问任何实例成员。虽然这有一些道理,但我并不总是急于跑出去这样做有几个原因:

  1. 命名空间污染。如果我们养成这种习惯,就会开始有“好日子”的味道,那时一切都集中在全局模块中,你可以随意调用函数。一想到我就不寒而栗。诚然,静态方法被组织成类和命名空间,但它们仍然不是特定于实例的,它们对我来说只是全局函数的味道。它们让我的脚趾像黑板上指甲的声音一样卷曲。

  2. 仅仅因为一个方法今天不访问实例变量并不意味着它明天不会。重构它来做到这一点是一个突破性的变化。使方法静态化不是一个应该轻易做出的决定。您这样做是因为您知道该方法旨在以这种方式使用,而不是因为工具注意到今天您没有使用实例变量。

现在,话虽如此,我确实相信静态方法有一个非常有用的目的,并且如果使用得当,可以出色地解决无数问题。当我打算和非常特定的目的时,我会使用它们,而这些目的通常与 Resharper 是否认为我应该这样做无关。

我还没有看到任何说明如果方法被标记为静态,应用程序将更有效地执行。我可能倾向于认为静态类会降低性能,因为它们存在于应用程序的整个生命周期中,并且在应用程序超出范围之前它们分配的任何资源都不会被释放。(另一方面,根据实施情况,这可能会提高性能。)

最终,性能问题归结为实施。

于 2011-11-11T15:43:22.540 回答
0

我个人会让它们成为静态的。感觉更正确的是,如果某些东西在实例上不起作用,它不应该是实例上的成员(但在类上)。

例如,一个 add 方法接受两个参数并将它们相加并返回结果将不需要更多的处理自身,因此可以是静态的。如果您将其作为实例方法保留,则可能意味着它会有所不同,您在哪个实例上运行它显然不会!

我不认为在效率方面有任何优势(尽管我没有仔细研究过),只是在代码的可读性方面。

于 2011-11-11T15:32:42.720 回答