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

时间:2011-09-08 23:40:56

标签: c# coding-style static scope standards

我正在阅读Microsoft的一些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允许程序员将函数中的变量声明为static。例如,在此代码中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#不允许这样做。有什么特别的理由吗?在这种情况下,它似乎是完美的。它将变量范围限制为函数,并且仅在第一次初始化它。即使对象创建成本很高,也只会执行一次。那么为什么这个不可用呢?或者是吗?

感谢阅读!

3 个答案:

答案 0 :(得分:4)

  

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);
}

答案 1 :(得分:1)

正如ReSharper建议的那样,你有什么理由不想让它成为本地const吗?

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

答案 2 :(得分:1)

blog post in the C# FAQ about this exact question

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

此外,我很高兴这被遗漏了。状态,作为数据,它在C#中的方式,仅存在与类型或实例相关联。这将成为存储状态的第三种方式,并增加混乱。

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