简体   繁体   English

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

[英]Why does C# not allow variables to be declared static in methods?

I'm reading some AppHub samples by Microsoft and this is the beginning of one of the functions: 我正在阅读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 says to make this value a constant rather than redeclaring it every time. ReSharper表示要将此值设为常数,而不是每次都重新声明。 However, this string value is only used in this function, so making it a member variable should not be necessary. 但是,此字符串值仅在此函数中使用,因此不必将其设为成员变量。 Ideally, the variable's scope should be limited to this function. 理想情况下,变量的范围应限于此功能。 Right? 对?

Also, I agree with whoever is about to say "place the string in a resource file." 另外,我同意谁说“将字符串放入资源文件”。 In this case that would most likely be the optimal solution. 在这种情况下,最有可能是最佳解决方案。 Not only does it solve localization issues but it also saves the variable from being re-initialized every function call and no longer clutters up the source file. 它不仅解决了本地化问题,而且还避免了在每次函数调用时重新初始化变量,并且不再使源文件混乱。 However, this is just an example. 但是,这仅仅是一个例子。

I know many are probably going to say something along the lines of "premature optimization is the root of all evil" but please note this is just an example. 我知道许多人可能会说“过早的优化是万恶之源”,但请注意,这只是一个例子。 What if this quasi-constant variable was complex and re-initializing it every call would cause a noticeable slowdown? 如果该准常数变量很复杂,并且在每次调用时重新初始化它,会导致明显的速度下降怎么办?

Visual Basic .NET allows the programmer to declare variables in a function as static. Visual Basic .NET允许程序员将函数中的变量声明为静态。 For example, in this code TestFunction will only be called the first time I click the button: 例如,在此代码中, 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

As far as I know C# does not allow this. 据我所知,C#不允许这样做。 Is there any particular reason why? 有什么特别的原因吗? It seems like it would be perfect in this situation. 在这种情况下,这似乎是完美的。 It limits the variables scope to the function and only initializes it the first time around. 它将变量范围限制为该函数,并且仅在第一次使用时才对其进行初始化。 Even if object creation is costly it will only be performed once. 即使对象创建成本很高,也只会执行一次。 So why is this not available? 那么为什么这不可用? Or is it? 还是?

Thanks for reading! 谢谢阅读!

ReSharper says to make this value a constant rather than redeclaring it every time. ReSharper表示要将此值设为常数,而不是每次都重新声明。 However, this string value is only used in this function, so making it a member variable should not be necessary. 但是,此字符串值仅在此函数中使用,因此不必将其设为成员变量。 Ideally, the variable's scope should be limited to this function. 理想情况下,变量的范围应限于此功能。 Right? 对?

Yes, but resharper will make the local variable const, not create a member field 是的,但是重新共享会使本地变量为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);
}

Is there any reason why you don't want to make it a local const , as ReSharper suggests? 正如ReSharper建议的那样,您是否有任何理由不希望使其成为本地const

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

There is a blog post in the C# FAQ about this exact question . C#FAQ中一篇关于此确切问题博客文章

Effectively, there are two reasons. 实际上,有两个原因。 First, you can accomplish the same thing via a const or via a member level static variable in nearly all situations. 首先,几乎在所有情况下,您都可以通过const或成员级静态变量来完成同一件事。 Secondly, local static variables in other languages (like C and C++) frequently cause problems in multithreaded scenarios. 其次,其他语言(例如C和C ++)中的局部静态变量在多线程方案中经常引起问题。

In addition, I am happy this was left out. 另外,我很高兴这被排除在外。 State, as data, the way it is in C#, only exists tied to a type or to an instance. 状态作为数据,以其在C#中的方式,仅与类型或实例相关联。 This would be making a third way to store state, and add confusion. 这将成为存储状态并增加混乱的第三种方式。

As to why VB.Net included this - this was included for backwards compatibility with VB. 至于为什么VB.Net包含此内容-包含此内容是为了与VB向后兼容。 That being said, the compiler actually turns this into a static member of the type, so its really the same level of support as C#. 话虽这么说,编译器实际上将其转换为该类型的静态成员,因此其支持程度与C#相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM