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

发布于 2024-12-03 13:28:34 字数 1276 浏览 2 评论 0原文

我正在阅读 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# 不允许这样做。有什么特别的原因吗?在这种情况下,似乎就很完美了。它将变量范围限制在函数内,并且仅在第一次时对其进行初始化。即使对象创建的成本很高,它也只会执行一次。那么为什么这个不可用呢?或者是吗?

感谢您的阅读!

I'm reading some AppHub samples by Microsoft and this is the beginning of one of the functions:

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. 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. For example, in this code TestFunction will only be called the first time I click the button:

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. 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

渔村楼浪 2024-12-10 13:28:34

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 says to make this value a constant rather than redeclaring
it every time. 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

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);
}
夜灵血窟げ 2024-12-10 13:28:34

您是否有任何理由不想将其设为本地 const,正如 ReSharper 所建议的那样?

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

Is there any reason why you don't want to make it a local const, as ReSharper suggests?

if (string.IsNullOrEmpty(textureFilename))
{
    const string message = "...";
    throw new InvalidOperationException(message);
}
爱的故事 2024-12-10 13:28:34

有一个 C# 常见问题解答中有关此确切问题的博客文章

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

此外,我很高兴这一点被排除在外。状态,就像 C# 中的数据一样,只存在于类型或实例中。这将成为存储状态的第三种方式,并增加混乱。

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

There is a blog post in the C# FAQ about this exact question.

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. Secondly, local static variables in other languages (like C and C++) frequently cause problems in multithreaded scenarios.

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. 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. 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#.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文