当创建一个具有内部私有方法(通常是为了减少代码重复)的类时,不需要使用任何实例字段,将方法声明为静态是否有性能或内存优势?

例子:

foreach (XmlElement element in xmlDoc.DocumentElement.SelectNodes("sample"))
{
    string first = GetInnerXml(element, ".//first");
    string second = GetInnerXml(element, ".//second");
    string third = GetInnerXml(element, ".//third");
}

...

private static string GetInnerXml(XmlElement element, string nodeName)
{
    return GetInnerXml(element, nodeName, null);
}

private static string GetInnerXml(XmlElement element, string nodeName, string defaultValue)
{
    XmlNode node = element.SelectSingleNode(nodeName);
    return node == null ? defaultValue : node.InnerXml;
}

将GetInnerXml()方法声明为静态有什么好处吗?请不要发表意见,我有自己的看法。


当前回答

是的,编译器不需要将隐式this指针传递给静态方法。即使你没有在你的实例方法中使用它,它仍然被传递。

其他回答

从FxCop规则页面:

将方法标记为静态后,编译器将向这些成员发出非虚拟调用站点。发出非虚拟调用站点将防止在运行时对每个调用进行检查,以确保当前对象指针是非空的。这可以为性能敏感代码带来可衡量的性能增益。在某些情况下,无法访问当前对象实例表示正确性问题。

由于没有传递this参数,它会稍微快一些(尽管调用该方法的性能成本可能比节省的成本要高得多)。

我想说,我能想到的私有静态方法的最好理由是,它意味着你不能意外地改变对象(因为没有this指针)。

这迫使您记住将函数使用的任何类作用域成员也声明为静态的,这将节省为每个实例创建这些项的内存。

当我编写一个类时,大多数方法分为两类:

使用/更改当前实例状态的方法。 Helper方法不使用/改变当前对象的状态,但帮助我计算我在其他地方需要的值。

静态方法很有用,因为仅通过查看它的签名,您就知道调用它不会使用或修改当前实例的状态。

举个例子:

public class Library
{
    private static Book findBook(List<Book> books, string title)
    {
        // code goes here
    }
}

如果库状态的实例发生了错误,并且我试图找出原因,那么仅从findBook的签名就可以排除它是罪魁祸首。

我尝试尽可能多地使用方法或函数的签名进行交流,这是一种很好的方式。

As has already been stated, there are many advantages to static methods. However; keep in mind that they will live on the heap for the life of the application. I recently spent a day tracking down a memory leak in a Windows Service... the leak was caused by private static methods inside a class that implemented IDisposable and was consistently called from a using statement. Each time this class was created, memory was reserved on the heap for the static methods within the class, unfortunately, when the class was disposed of, the memory for the static methods was not released. This caused the memory footprint of this service to consume the available memory of the server within a couple of days with predictable results.