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

为什么C#不允许在方法中声明静态变量?,c#,coding-style,static,scope,standards,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 partic

我正在阅读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允许程序员将函数中的变量声明为静态变量。例如,在此代码中,仅当我第一次单击按钮时才会调用
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#不允许这样做。有什么特别的原因吗?在这种情况下,它似乎是完美的。它将变量的作用域限制为函数,并且仅在第一次初始化它。即使对象创建成本很高,也只会执行一次。那么,为什么这不可用呢?还是这样


谢谢你的阅读

你有什么理由不想像ReSharper建议的那样,把它变成本地的
常量

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

有什么理由不想让它成为ReSharper建议的本地
const

if (string.IsNullOrEmpty(textureFilename))
{
    const string message = "...";
    throw new InvalidOperationException(message);
}
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);
}
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
或通过成员级静态变量来完成相同的任务。其次,其他语言(如C和C++)中的局部静态变量在多线程场景中经常导致问题

此外,我很高兴这被遗漏了。状态作为数据(在C#中的方式)只存在于绑定到类型或实例的情况下。这将是第三种存储状态的方法,并增加混乱

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

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

此外,我很高兴这被遗漏了。状态作为数据(在C#中的方式)只存在于绑定到类型或实例的情况下。这将是第三种存储状态的方法,并增加混乱


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

我不知道为什么它不可用。(可能是因为VB.NET是一种稍好一点的语言:)不过,将其作为成员变量并不坏——尽管在范围方面有点问题,但单个类文件应该由同一个人编写,而且变量的用途应该很明显。VB中的静态“局部变量”只是一个编译器技巧。生成的IL与使用类级静态字段没有什么不同(除了编译器生成的名称)。我不知道为什么它不可用。(可能是因为VB.NET是一种稍好一点的语言:)不过,将其作为成员变量并不坏——尽管在范围方面有点问题,但单个类文件应该由同一个人编写,而且变量的用途应该很明显。VB中的静态“局部变量”只是一个编译器技巧。生成的IL与您使用类级静态字段(除了编译器生成的名称)没有什么不同。O_O不知道您可以这样做。老实说,我甚至都没有费心重新整理它,因为我觉得它只是将它作为常量成员变量放在类中。O_O不知道你可以这样做。老实说,我甚至都没有费心重新复调它,因为我想它只是将它作为常量成员变量放在类中。嘿,我脸上有鸡蛋。我不知道方法中可以有常量变量。在一个方法中的一个静态变量不起作用之后,我甚至不想尝试静态变量。另外,我想我假设如果可能的话,微软会在他们的代码中完成这项工作。哦,好的,谢谢@凯尔:当然你不能有“常量变量”,因为“常量”和“变量”是对立的。(可以有局部常量,但它们不是“常量变量”。)在C#中没有局部作用域的静态字段;如果您想要一个静态字段,那么就创建一个私有类范围的静态字段。H