1

静态定义和使用方法而不是使用实例化类中的方法是否存在内存或性能差异?当方法不是静态的时,方法本身是否会占用类的每个实例的内存?

也许在静态方法中声明的任何变量都是非线程安全的?

/// <summary>
/// A class using instance methods (non-static)
/// </summary>
public class Junk
{
    public int x {get; protected set;}
    public Junk(int x = 0)
    {
        this.x = x;
    }
    public void Increment()
    {
        this.x++;
    }
}

相对

/// <summary>
/// A class using static methods
/// </summary>
public class Junk
{
    public int x {get; protected set;}
    public Junk(int x = 0)
    {
        this.x = x;
    }
    public static void Increment(Junk thisJunk)
    {
        thisJunk.x++;
    }
}
4

4 回答 4

7

没有区别。正如您的示例所示,实例方法在逻辑上只不过是第一个参数名为“this”的静态方法。唯一的区别是在实例方法中自动检查“this”是否为空;它不在静态方法中。

现在,虚拟方法确实会导致性能成本,因为实际调用的方法必须在运行时计算,而不是在编译时计算。这可能会使程序的运行时间增加几纳秒,并且还排除了某些优化,例如内联。

至于线程安全:变量是否安全使用是整个程序的属性,而不是方法是否为静态的属性。

于 2013-04-15T16:48:05.620 回答
2

不; 实例方法不占用每个实例的任何空间。即使是虚拟方法也不这样做——所有实例都只使用一个方法表。

也就是说,有一个非常小的性能差异:实例方法将this引用作为隐藏参数,调用站点可能需要检查空引用。这使得调用该方法的成本略高,但差异几乎无关紧要。

尽管在您的示例中,我高度怀疑 JIT 编译器会内联该方法(无论它是否是静态的)并以任何一种方式生成相同的代码。

于 2013-04-15T16:47:47.180 回答
1

在静态方法中声明的变量绝对不是静态的。见前,http://blogs.msdn.com/b/csharpfaq/archive/2004/05/11/why-doesn-tc-support-static-method-variables.aspx

这是一个更新的常见问题解答:http: //msdn.microsoft.com/en-us/library/79b3xss3.aspx:“C# 不支持静态局部变量(在方法范围内声明的变量)。”

于 2013-04-15T17:17:11.493 回答
0

静态方法和实例方法不可互换。它们用于完全不同的情况以解决完全不同的问题。您应该使用适合您想要做的任何类型的方法。

由于您不会处于任何一种方法都适合手头任务的位置,因此两种方法之间的性能差异(如果有)是无关紧要的。你应该做在逻辑上和语义上适合你的程序的事情。

于 2013-04-15T17:36:54.833 回答