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 假设是非条块内读.那么就至少涉及到两个条块的读,这就须要 ...
 
随机推荐
- App Store不能下载一直等待中的两种解决办法
			
1,重启手机,之后确认是否得到改善 2,重启不行,更改WiFi的dns为114.114.114.114或者223.5.5.5 或 223.6.6.6,再重启手机 ps:我是第二种方法
 - stagefright框架(一)Video Playback的流程
			
在Android上,預設的多媒體框架(multimedia framework)是OpenCORE. OpenCORE的優點是兼顧了跨平台的移植性,而且已經過多方驗證,所以相對來說較為穩定:但是其缺點 ...
 - [AngularJS系列(4)] 那伤不起的provider们啊~ (Provider, Value, Constant, Service, Factory, Decorator)(转)
			
用AngularJS做项目,但凡用过什么service啊,factory啊,provider啊,开始的时候晕没晕?!晕没晕?!感觉干的事儿都差不多啊,到底用哪个啊?!别告诉我你们几个就是为了跟我炫耀兄 ...
 - 禁掉a链接的几种方法
			
这次遇到链接 先留着 但不能有任何作用的需求 ,我只能说顾客的需求真是多种多样,奇奇怪怪啊 啊啊啊啊啊啊啊啊啊啊啊 我用span代替了a 标签,但是后来想想维护起来可能不太方便 所以上网查资料, ...
 - ASP.NET基于donetCHARTING的自动报表
			
1,首先需要添加引用ChartExtents.dll和donetCHARTING.dll,资源百度大把. 2,配置图片生成类. using System; using System.Data; usi ...
 - Android开发_关于如何屏蔽Home键
			
今天在遇到一个要屏蔽Home键的问题,研究一上午终于解决,方法记录于下: 在Android2.3版本以下重写以下方法就能屏蔽Home键: public void onAttachedToWindow( ...
 - 宏定义 define
			
#define kOut -1 用一个字符串代替一个数据 用kOut表示-1(一般开头有一个小写的k) 作用: 1.为了让一些数据有意义 #define kUseId asdjlfdjafa #def ...
 - vim中使用gdb。
			
引用文章A:http://easwy.com/blog/archives/advanced-vim-skills-vim-gdb-vimgdb/ 引用介绍:使用vimgdb来完成gdb的嵌入. 需要的 ...
 - Android进程
			
android进程等级 1.前台进程 2.可视进程 3.服务进程 4.后台进程 5.空进程 让应用退出方式 finish();让应用成为空进程 Process.killProcess();杀进程 sy ...
 - HTML5 Web存储(Web Storage)技术及用法
			
在如今的Web开发中,HTML5是大家讨论的最大一个话题.HTML5提供的新功能特征使得Web程序员如虎添翼,并免去了以往钻研各种方法来让网站更好.更快.更灵活的气力.这些新功能中有一个非常让我感兴趣 ...