![]() |
1
17
这个 Microsoft C#4 Spec 与以前的版本略有不同,现在更准确地反映了我们在这里看到的行为:
这个
ECMA Spec
以及
Microsoft C#3 Spec
两者都在该列表中有一个额外的事件:“引用了结构类型的实例成员”。
编辑… 经过进一步的调查,几乎所有的实例成员访问 除了 直接字段访问将触发静态构造函数(至少在当前的Microsoft C 3和4实现中)。 因此,当前的实现与ECMA和C 3规范中给出的规则比C 4规范中给出的规则更为密切相关:访问所有实例成员时,C 3规则是正确实现的。 除了 字段;C 4规则是 只有 正确实施现场访问。 (当涉及到与静态成员访问和显式声明的构造函数相关的规则时,不同的规范都是一致的——并且显然是正确实现的。) |
![]() |
2
11
来自本标准第18.3.10节(另见 The C# programming language 书):
所以我同意你的程序最后两行应该触发第一条规则。 在测试之后,人们的共识似乎是,它总是触发方法、属性、事件和索引器。这意味着它对所有显式实例成员都是正确的 除了 领域。因此,如果为标准选择了微软的C 4规则,这将使其实现从基本正确到基本错误。 |
![]() |
3
1
这是疯狂的设计行为的“beforefieldinit”属性在msil。它也影响了C++/CLI,我提交了一个bug报告,其中微软很好地解释了为什么行为是这样的,并且我指出了语言标准中不同意/需要更新以描述实际行为的多个部分。但这是不公开的。总之,这里是微软的最后一个字(讨论C++中类似的情况):
同样的行为就是你所看到的,尽管用的是不同的语言。 |
![]() |
4
1
另一个有趣的例子:
|
![]() |
5
1
更新: 我的观察是,除非使用静态状态,否则将永远不会接触静态构造函数——运行时似乎决定了这一点,并且不适用于引用类型。这就回避了这样一个问题:它是因为影响很小而留下的一个bug,还是因为设计原因,或者它是一个悬而未决的bug。 更新2: 就个人而言,除非您在构造函数中做了一些奇怪的事情,否则运行时的这种行为永远不会引起问题。一旦您访问静态状态,它就会正常工作。 更新3: 除了Lukeh的注释之外,参考Matthew Flaschen的答案,在结构中实现和调用自己的构造函数也会触发调用静态构造函数。这意味着,在三种情况中,有一种情况下,行为并不是它在锡上所说的。 我刚向类型添加了一个静态属性,并访问了该静态属性——它称为静态构造函数。如果不访问静态属性,只创建类型的新实例,则不会调用静态构造函数。
此链接中的注释指定静态构造函数是 不 仅访问实例时调用: |
![]() |
6
1
把这个作为一个“答案”,这样我就可以分享里克特先生自己写的关于它的文章(顺便问一下,是否有人有一个最新的clr规范的链接,它很容易获得2006年的版本,但是发现要获得最新的版本有点困难): 对于这类东西,查看clr规范通常比查看c规范要好。clr规范说: 4。如果未标记beforefieldinit,则该类型的初始化器方法将在执行(即,由以下触发): _窆首次访问该类型的任何静态字段,或 _窆首次调用该类型的任何静态方法或 _窆,如果是值类型或 _窆首次调用该类型的任何构造函数。 由于这些条件都不满足,静态构造函数是 不 调用。唯一需要注意的是,__u x__是一个实例字段,而不是静态字段,构造一个结构数组可以 不 对数组元素调用任何实例构造函数。 |
![]() |
7
0
我猜您正在创建一个值类型的数组。因此,新的关键字将用于初始化数组的内存。 可以这么说
任何地方都没有新的关键字,这基本上就是你在这里所做的。如果somevaltype是引用类型,则必须使用
|