为什么C#不允许在方法中声明静态变量?
我正在阅读Microsoft提供的一些AppHub示例,这是其中一个函数的开始:为什么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
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