使用静态构造函数(Jon Skeet Brainteaser)
作为一个相对新手,我尝试尽可能多地阅读有关特定主题的内容,并尽可能多地测试/编写代码。我正在查看其中一个 Jons Brainteasers (问题#2),我的输出是与答案不同。这使得我来到这里询问最近版本中是否发生了某些变化,并查看其他人从这段代码中得到了什么输出。
问题是,“将展示什么,为什么,以及你有多大信心?”
using System;
class Foo
{
static Foo()
{
Console.WriteLine ("Foo");
}
}
class Bar
{
static int i = Init();
static int Init()
{
Console.WriteLine("Bar");
return 0;
}
}
class Test
{
static void Main()
{
Foo f = new Foo();
Bar b = new Bar();
}
}
如果有的话,什么会导致我们得到两个不同的答案?
As a relative newbie I try to read as much as I can about a particular subject and test/write as much code as I can. I was looking at one of Jons Brainteasers (question #2) and my output was different than the answer. Which makes brings me here to ask if something has changed in recent versions and to see what output others are getting from this code.
The question is, "What will be displayed, why, and how confident are you?"
using System;
class Foo
{
static Foo()
{
Console.WriteLine ("Foo");
}
}
class Bar
{
static int i = Init();
static int Init()
{
Console.WriteLine("Bar");
return 0;
}
}
class Test
{
static void Main()
{
Foo f = new Foo();
Bar b = new Bar();
}
}
What, if anything, would cause us to get two different answers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
现在在调试器之外的发布模式下尝试它;-p
使用/不使用调试器时我会得到不同的结果。调试器扰乱了很多微妙的细微差别/优化,所以我只能猜测这是调试器很重要的时候之一。这使得调试变得更加困难;-p
Now try it in release mode, outside of the debugger ;-p
I get different results with/without a debugger. The debugger upsets a lot of subtle nuances / optimisations, so I can only guess this is one of those times where the debugger matters. Which makes it even harder to debug ;-p
Jon 自己的答案页面对此进行了讨论。我不是 C# 人员,但系统似乎只有一种选择何时调用静态 foo 代码(因此写为“Foo”),但它本质上有无限的自由来决定何时调用初始化
Bar.i
(它将写入“Bar”),因此它可以在类加载时发生,或者在第一次使用时发生,或者根本不发生。Jon's own answers page discusses this. I'm not a C# guy, but it seems like the system has exactly one choice of when to call the static
foo
code (and therefore write "Foo") but it has essentially infinite freedom to decide when to initializeBar.i
(which will write "Bar"), so it can happen either when the class is loaded, or when it is first used, or not at all.它在调试模式下打印 Foo, Bar,在发布模式下打印 Bar, Foo。因此,发生的情况是 Release 代码被优化,并且优化导致 Bar 首先被调用 - 但不保证情况总是如此。
It prints Foo, Bar in Debug mode and Bar, Foo in Release mode. So what is happening is the Release code is optimized and the optimization causes Bar to be called first - but there is no guarantee that will always be the case.
只要看看它,如果它显示除“FooBar”之外的其他内容,我会感到惊讶。
原因很简单,您首先访问 Foo,因此它的静态构造函数将运行。实例化 Bar 时紧随其后的是静态字段初始值设定项。
很高兴被纠正。
Just looking at it, I'd be surprised if it displayed anything else but "FooBar".
For the simple reason you are accessing Foo first, so its static constructor will run. Followed by the static field initializer when instantiating Bar.
Happy to be corrected.
我认为 foo bar 将会被打印。静态类型构造函数将首先在 Foo 中执行,然后在 Bar 类上调用 Init 方法。我不知道这种行为是否会改变。这很有趣。
I think that foo bar will be printed. The static type constructor would be executed first in Foo, then the Init method would be called on the Bar class. I don't know about whether or not the behavior could change though. This is interesting.