C#中的BeforeFieldInit
来源:互联网 发布:白芨吉利知胃病中草药 编辑:程序博客网 时间:2024/06/04 19:11
今天学习设计模式中的单例模式,无意间发现了这个标志BeforeFieldInit。
于是简单地搜索了一下,总结出如下内容。
The C# specification states:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
* An instance of the class is created.
* Any of the static members of the class are referenced.
The CLI specification (ECMA 335) states in section 8.9.5:
- A type may have a type-initializer method, or not.
- A type may be specified as having a relaxed semantic for its type-initializer method (for convenience below, we call this relaxed semantic 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 (i.e., is triggered by):
- first access to any static or instance field of that type, or
- first invocation of any static, instance or virtual method of that type
The C# specification implies that no types with static constructors should be marked with the BeforeFieldInit flag.
换句话说,如果一个类(型)没有静态构造函数,那么它应该被标记为BeforeFieldInit。也就是说,这个类(型)的初始化工作有可能早于,晚于或者就在这个类(型)的静态属性被访问时完成。
文章《What does beforefieldinit flag do?》给出的解释更简单。
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.
下面我们来看个例子。
using System;namespace BeforeFieldInit{ class Demo { static Demo() { Console.WriteLine("Run static constructor"); } public static string x = Print("Initialize Type"); public static string Print(string message) { Console.WriteLine(message); return message; } } class Program { static void Main(string[] args) { // Start Console.WriteLine("Starting Main"); // Invoke a static method on Test Demo.Print("Call print function."); Console.WriteLine("After calling Print."); // Reference a static field in Test string y = Demo.x; Console.WriteLine("After accessing field."); } }}
运行后得到的结果如下:
Starting Main
Initialize Type
Run static constructor
Call print function.
After calling Print.
After accessing field.
把静态构造函数注释掉,运行后得到的结果如下:
Initialize Type
Starting Main
Call print function.
After calling Print.
After accessing field.
我们发现在main函数里,我们还没有访问Demo类,Demo类的静态变量的初始化工作就已经完成了。这就是前面提到的早于的意思。理论上晚于或者就在也应该可以发生的,只是我没有重现出来。
References
C# and beforefieldinit
What does beforefieldinit flag do?
- C#中的BeforeFieldInit
- C# and beforefieldinit
- 关于静态构造函数和BeforeFieldInit
- C#中的@
- C# 中的 @
- c#中的??
- C#中的??
- C#中的“?”
- [原创] 关于Type Initializer和 BeforeFieldInit的问题,看看大家能否给出正确的解释
- 关于Type Initializer和 BeforeFieldInit的问题,看看大家能否给出正确的解释
- C#中的问号 C#中的问号
- javascript中的+和C#中的+
- C#中的cookie编程
- C#中的函数指针
- C#中的接口
- C#中的正则表达式
- C#中的cookie编程
- C#中的cookie编程
- springmvc在controller中return视图跳转不了
- JavaScript设计模式--开篇
- 互联网公司面试套路
- android 相对布局
- Java多线程1:进程与线程
- C#中的BeforeFieldInit
- C++网路编程(2)
- Python学习笔记(11) -- (关键词:sorted/列表/字典/排序/键/值)
- Process Monitor —— 程序(文件和注册表)监控
- github如何更新fork的代码
- webjs--全选和全不选的复选框
- php的新特性
- 浅谈Android Variants(Android变体)
- android 应用内悬浮框,并在指定页面显示