为什么c#不允许在方法中将变量声明为静态?

本文关键字:声明 变量 静态 不允许 方法 为什么 | 更新日期: 2023-09-27 18:08:17

我正在阅读微软的一些AppHub示例,这是其中一个函数的开头:

if (string.IsNullOrEmpty(textureFilename))
{
    string message = "textureFilename wasn't set properly, so the " +
        "particle system doesn't know what texture to load. Make " +
        "sure your particle system's InitializeConstants function " +
        "properly sets textureFilename.";
    throw new InvalidOperationException(message);
}

ReSharper说把这个值设为常量,而不是每次都重新声明。然而,这个字符串值只在这个函数中使用,所以没有必要将其作为成员变量。理想情况下,变量的作用域应该限制在这个函数中。对吧?

另外,我同意即将说"将字符串放在资源文件中"的人的说法。在这种情况下,这很可能是最优解决方案。它不仅解决了本地化问题,而且还避免了每次函数调用都重新初始化变量,并且不再使源文件混乱。然而,这只是一个例子。

我知道很多人可能会说"过早优化是万恶之源",但请注意这只是一个例子。如果这个准常量变量很复杂,并且每次调用都重新初始化它会导致明显的减速,那该怎么办?Visual Basic . net允许程序员将函数中的变量声明为静态。例如,在这段代码中,TestFunction将只在我第一次单击按钮时被调用:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Static example As Integer = TestFunction()
    MessageBox.Show(example)
End Sub
Private Function TestFunction() As Integer
    Console.WriteLine("Method Accessed")
    Return 5
End Function

据我所知c#不允许这样做。有什么特别的原因吗?在这种情况下,它似乎是完美的。它将变量范围限制在函数中,并且只在第一次初始化它。即使对象创建是昂贵的,它也只执行一次。那么为什么这是不可用的呢?是吗?

感谢阅读!

为什么c#不允许在方法中将变量声明为静态?

ReSharper说把这个值设为常量而不是重新声明每次都是。但是,此字符串值仅在此中使用函数,因此没有必要将其设置为成员变量。理想情况下,变量的作用域应该限制在这个函数中。对吧?

可以,但是resharper将使局部变量为const,而不是创建成员字段

if (string.IsNullOrEmpty(textureFilename))
{
    const string message = "textureFilename wasn't set properly, so the " +
        "particle system doesn't know what texture to load. Make " +
        "sure your particle system's InitializeConstants function " +
        "properly sets textureFilename.";
    throw new InvalidOperationException(message);
}

您是否有任何理由不想使其成为本地const,如ReSharper所建议的?

if (string.IsNullOrEmpty(textureFilename))
{
    const string message = "...";
    throw new InvalidOperationException(message);
}

c#常见问题解答中有一篇关于这个问题的博文。

实际上,有两个原因。首先,在几乎所有情况下,您都可以通过const或成员级静态变量来完成相同的事情。其次,其他语言(如C和c++)中的局部静态变量经常在多线程场景中导致问题。

另外,我很高兴这被省略了。状态就像c#中的数据一样,只与类型或实例绑定在一起。这将创建第三种存储状态的方法,并增加混乱。

至于为什么VB。Net包含了这个-这是为了向后兼容VB。话虽如此,编译器实际上将它转换为类型的静态成员,因此它的支持级别与c#相同。