beforefieldinit释义
首先让我们认识什么是,当字段被标记为beforefieldinit类型时,该字段初始化可以发生在任何时候任何字段被引用之前。这句话听起了有点别扭,接下来让我们通过具体的例子介绍。
/// <summary>
/// Defines a test class.
/// </summary>
class Test
{
public static string x = EchoAndReturn("In type initializer"); public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}
上面我们定义了一个包含静态字段和方法的类Test,但要注意我们并没有定义静态的构造函数。

图3 Test类的IL代码
class Test
{
public static string x = EchoAndReturn("In type initializer"); // Defines a parameterless constructor.
static Test()
{
} public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}
上面我们给Test类添加一个静态的构造函数。

图4 Test类的IL代码
通过上面Test类的IL代码的区别我们发现,当Test类包含静态字段,而且没有定义静态的构造函数时,该类会被标记为beforefieldinit。
现在也许有人会问:“被标记为beforefieldinit和没有标记的有什么区别呢”?OK现在让我们通过下面的具体例子看一下它们的区别吧!
class Test
{
public static string x = EchoAndReturn("In type initializer"); static Test()
{
} public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
} class Driver
{
public static void Main()
{
Console.WriteLine("Starting Main");
// Invoke a static method on Test
Test.EchoAndReturn("Echo!");
Console.WriteLine("After echo");
Console.ReadLine(); // The output result:
// Starting Main
// In type initializer
// Echo!
// After echo
}
}
我相信大家都可以得到答案,如果在调用EchoAndReturn()方法之前,需要完成静态成员的初始化,所以最终的输出结果如下:

图5输出结果
接着我们在Main()方法中添加string y = Test.x,如下:
public static void Main()
{
Console.WriteLine("Starting Main");
// Invoke a static method on Test
Test.EchoAndReturn("Echo!");
Console.WriteLine("After echo"); //Reference a static field in Test
string y = Test.x;
//Use the value just to avoid compiler cleverness
if (y != null)
{
Console.WriteLine("After field access");
}
Console.ReadKey(); // The output result:
// In type initializer
// Starting Main
// Echo!
// After echo
// After field access }

图6 输出结果
通过上面的输出结果,大家可以发现静态字段的初始化跑到了静态方法调用之前,Wo难以想象啊!
最后我们在Test类中添加一个静态构造函数如下:
class Test
{
public static string x = EchoAndReturn("In type initializer"); static Test()
{
} public static string EchoAndReturn(string s)
{
Console.WriteLine(s);
return s;
}
}

图7 输出结果
理论上,type initializer应该发生在”Starting Main”之后和”Echo!”之前”,但这里却出现了不唯一的结果,只有当Test类包含静态构造函数时,才能确保type initializer的初始化发生在”Starting Main”之后和”Echo!”之前”。
所以说要确保type initializer发生在被字段引用时,我们应该给该类添加静态构造函数。
beforefieldinit释义的更多相关文章
- beforefieldinit释义(3)
1.看下面的例子: public static class MyClass<T> { public static readonly DateTime Time = GetNow(); pr ...
- beforefieldinit释义(2)
首先来看一段代码: using System; namespace BeforeFieldInit { internal class Foo { Foo(){ Console.WriteLine(&q ...
- 常见linux命令释义(第八天)—— Bash Shell 的操作环境
换了新公司,公司的领导很不错.自己感受比较多的地方是,自己的工作效率明显比以前高了.以前会对频繁变动的需求十分不耐烦,现在接到需求后会仔细的思考,进行整体构建.即使以后需求有变动,也能够比较轻易的在原 ...
- 常见linux命令释义(第三天)
今天晚上看鸟哥的私房菜,边学边写笔记. 在linux中压缩大多是.tar, .tar.gz , .tgz, /gz, .bz2等. .gz 是通过gzip压缩的文件. .bz2 是通过bzip2压缩的 ...
- 常见linux命令释义(第一天)
快到中午吃饭了,然后忽然想起来samba里面没有添加用户.于是乎,就玩弄起了samba. Samba三下五除二就安装好了,想想window里面不断的点击下一步,还要小心提防各种隐藏再角落里的绑定软件. ...
- Tomcat的目录结构、处理流程、主配置文件(server.xml)释义
参考资料: http://www.cnblogs.com/xdp-gacl/p/3744053.html http://grass51.blog.51cto.com/4356355/1123400 1 ...
- 使用Perl5获取有道词典释义
Get Word Definition from dict.youda.com via Perl Script 获取基本释义 Get Basic Definition http://dict.youd ...
- Web前端名词释义及原理
引言:看题目的时候,不要觉得这是一个很深奥的问题,Web前端这些东西很多就是叫的名字牛逼,其实原理很TM简单,也就那么回事. 一.javascript名词释义 1.啥是事件队列? 就是 弄一个数组,里 ...
- linux内核的冒险md来源释义# 14raid5非条块读
linux内核的冒险md来源释义# 14raid5非条块读 转载请注明出处:http://blog.csdn.net/liumangxiong 假设是非条块内读.那么就至少涉及到两个条块的读,这就须要 ...
随机推荐
- [WARNING] Warning: selected war files include a WEB-INF/web.xml which will be ignored (webxml attribute is missing from war task, or ignoreWebxml attribute is specified as 'true')
WARNING] Warning: selected war files include a WEB-INF/web.xml which will be ignored (webxml attribu ...
- java学习——数组
元素类型[] 数组名 = new 元素类型[元素个数或数组长度]; array 为引用数据类型|-数组数据类型 | 内存结构:程序在运行时,需要在内存中的分配空间.为了提高运行的效率,有对空间进行不同 ...
- Spring 入门 Ioc-Xml
通过一个小例子演视怎么通过 Spring 往程序中注入对象,而非手动 new 对象. 一.导入 Spring 所需要的包 spring-framework-2.5.6 版需要导入以下包: 1.---- ...
- IOS开发系列 --- 核心动画
原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...
- 转:C#: static关键字的作用
tatic意思是静态,可以修饰类.字段.属性.方法 标记为static的就不用创建实例对象调用了,可以通过类名直接点出来 static三种用法: 1.用于变量前,表示每次重新使用该变量所在方法.类或自 ...
- hdu2304Electrical Outlets
Problem Description Roy has just moved into a new apartment. Well, actually the apartment itself is ...
- MySTLString
auto ptr = new char[10]; delete ptr; delete 一个动态数组不能直接delete ptr, 应该是 delete[] ptr;
- 小项目--反eclass
前言—— 最近会把前一段时间闲的无聊写的一些很小的项目写一些博客,用来练练手. 引子—— 最近班里有个很讨厌的软件,,,,教育局规定每个学校要上传多媒体使用记录,所以学校就给班里每台电脑上装了一个比较 ...
- 多行文本垂直居中div高度确定
父元素高度确定的多行文本.图片.块状元素的垂直居中的方法有两种: 方法一:将内容写入table(包括tbody.tr.td)中的td标签里,同时设置 vertical-align:middle. cs ...
- asp.net后台向前端输出js脚本的三种方法
//这个方法最快,因为它会输出到html标签之前 Response.Write("<script type='text/javascript'>alert('这个最快')< ...