beforefieldinit 标志有什么作用?
beforefieldinit 标志有什么作用? 当我查看班级的 IL 时,我看到这个标志,但我不知道这个标志实际上在做什么?
What does beforefieldinit flag do?
When I look into the IL of my class I see this flag but I don't know what this flag is actually doing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请参阅关于此问题的我的文章。
基本上,beforefieldinit 的意思是“可以在引用任何静态字段之前的任何时候初始化该类型”。 理论上,这意味着它可以非常延迟初始化 - 如果您调用不触及任何字段的静态方法,JIT 不需要初始化该类型。
实际上这意味着该类的初始化早比其他情况要早 - 可以在第一个方法开始时对其进行初始化,可能< /em> 使用它。 将此与未应用
beforefieldinit
的类型进行比较,其中类型初始化必须在第一次实际使用之前立即进行。因此,假设我们有:
如果两种类型都应用了
beforefieldinit
(在 C# 中,除非该类型具有静态构造函数,否则它们默认这样做),那么它们将都在 DoSomething 方法开始时初始化(通常 - 不能保证)。 如果它们没有beforefieldinit
,那么根据标志,只会初始化其中的一个。这就是为什么在实现单例模式<时通常使用静态构造函数(甚至是空的构造函数!) /a>.
See my article on this very issue.
Basically,
beforefieldinit
means "the type can be initialized at any point before any static fields are referenced." In theory that means it can be very lazily initialized - if you call a static method which doesn't touch any fields, the JIT doesn't need to initialize the type.In practice it means that the class is initialized earlier than it would be otherwise - it's okay for it to be initialized at the start of the first method which might use it. Compare this with types which don't have
beforefieldinit
applied to them, where the type initialization has to occur immediately before the first actual use.So, suppose we have:
If both types have
beforefieldinit
applied to them (which in C# they do by default unless the type has a static constructor) then they'll both be initialized at the start of theDoSomething
method (usually - it's not guaranteed). If they don't havebeforefieldinit
then only one of them will be initialized, based on the flag.This is why it's common to use a static constructor (even an empty one!) when implementing the singleton pattern.
看起来它会在 4.6 中发生变化
https://github.com/dotnet/coreclr/issues /1193
Looks like it is going to change in 4.6
https://github.com/dotnet/coreclr/issues/1193
引用自“CA1810:初始化引用类型静态字段内联(代码分析)- .NET | Microsoft Docs”,重点是我的,TL;DR 位于底部:
TL;DR:
beforefieldinit
标志有助于避免静态构造函数检查,这有助于提高性能(因为检查会影响性能)。 它通过告诉 JIT 在实际静态字段使用之前运行静态构造函数来实现此目的。Quote from “CA1810: Initialize reference type static fields inline (code analysis) - .NET | Microsoft Docs” with emphasis mine and TL;DR at the bottom:
TL;DR:
beforefieldinit
flag helps avoid static constructor checks, which helps in performance (since the checks can affect performance). It does this by telling the JIT to run static constructors before the actual static field usage.如果标记为 BeforeFieldInit,则在首次访问为该类型定义的任何静态字段时或之前执行该类型的初始化方法。
如果未标记 BeforeFieldInit,则该类型的初始化方法将在
首先访问该类型的任何静态或实例字段,或者
首次调用该类型的任何静态、实例或虚拟方法。
If marked BeforeFieldInit then the type's initializer method is executed at, or sometime before, first access to any static field defined for that type.
If not marked BeforeFieldInit then that type's initializer method is executed at
first access to any static or instance field of that type, or
first invocation of any static, instance or virtual method of that type.