首先让我们认识什么是,当字段被标记为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释义的更多相关文章

  1. beforefieldinit释义(3)

    1.看下面的例子: public static class MyClass<T> { public static readonly DateTime Time = GetNow(); pr ...

  2. beforefieldinit释义(2)

    首先来看一段代码: using System; namespace BeforeFieldInit { internal class Foo { Foo(){ Console.WriteLine(&q ...

  3. 常见linux命令释义(第八天)—— Bash Shell 的操作环境

    换了新公司,公司的领导很不错.自己感受比较多的地方是,自己的工作效率明显比以前高了.以前会对频繁变动的需求十分不耐烦,现在接到需求后会仔细的思考,进行整体构建.即使以后需求有变动,也能够比较轻易的在原 ...

  4. 常见linux命令释义(第三天)

    今天晚上看鸟哥的私房菜,边学边写笔记. 在linux中压缩大多是.tar, .tar.gz , .tgz, /gz, .bz2等. .gz 是通过gzip压缩的文件. .bz2 是通过bzip2压缩的 ...

  5. 常见linux命令释义(第一天)

    快到中午吃饭了,然后忽然想起来samba里面没有添加用户.于是乎,就玩弄起了samba. Samba三下五除二就安装好了,想想window里面不断的点击下一步,还要小心提防各种隐藏再角落里的绑定软件. ...

  6. Tomcat的目录结构、处理流程、主配置文件(server.xml)释义

    参考资料: http://www.cnblogs.com/xdp-gacl/p/3744053.html http://grass51.blog.51cto.com/4356355/1123400 1 ...

  7. 使用Perl5获取有道词典释义

    Get Word Definition from dict.youda.com via Perl Script 获取基本释义 Get Basic Definition http://dict.youd ...

  8. Web前端名词释义及原理

    引言:看题目的时候,不要觉得这是一个很深奥的问题,Web前端这些东西很多就是叫的名字牛逼,其实原理很TM简单,也就那么回事. 一.javascript名词释义 1.啥是事件队列? 就是 弄一个数组,里 ...

  9. linux内核的冒险md来源释义# 14raid5非条块读

    linux内核的冒险md来源释义# 14raid5非条块读 转载请注明出处:http://blog.csdn.net/liumangxiong 假设是非条块内读.那么就至少涉及到两个条块的读,这就须要 ...

随机推荐

  1. Oozie — What Why and How

    Oozie是什么? Oozie最初是Yahoo!为Hadoop开发的一个工作流调度器,一个工作流有多个Job组成.它允许用户提交由多个Job组成的工作流配置文件,这些Job既可以顺序执行,也可以并行执 ...

  2. Spring 入门 Ioc-Xml

    通过一个小例子演视怎么通过 Spring 往程序中注入对象,而非手动 new 对象. 一.导入 Spring 所需要的包 spring-framework-2.5.6 版需要导入以下包: 1.---- ...

  3. Hadoop配置文件-core-site.xml

     name value  Description   fs.default.name hdfs://hadoopmaster:9000 定义HadoopMaster的URI和端口  fs.checkp ...

  4. web在线聊天系统。非ajax轮询

    利用php的死循环和刷新缓冲区实现.   浏览器发送请求到PHP获取消息页面. php接收到来之浏览器请求后. 循环获取数据库里面的消息.   当存在消息的时候.PHP告诉浏览器.我有消息给你.你接受 ...

  5. 【搜索引擎Jediael开发笔记2】使用HttpClient下载网页至本地文件

    本文使用HttpClient根据url进行网页下载.其中 (1)HttpClient的相关知识请参见HttpClient基础教程 (2) package org.ljh.search.download ...

  6. has leaked ServiceConnection com.baidu.location.LocationClient

    02-06 05:01:52.806: E/ActivityThread(1120): Activity com.project.xxxActivity $1@45fc5af8 that was or ...

  7. WebView高危接口安全检测

    高危]WebView高危接口安全检测共2处详细内容:在Android系统4.3.1~3.0版本,系统webview默认添加了searchBoxJavaBridge_接口,如果未移除该接口可能导致低版本 ...

  8. printf--动态指定输出格式长度

    char a1[] = {'A', 'B', 'C'}; char a2[] = "world"; printf(, a1, , a2); printf("[%.*s][ ...

  9. PendingIntent概述

    一.定义 PendingIntent表示待定.等待.即将发生的意思.Intent表示的是立刻发生. PendingIntent的主要方法: int requestCode:表示请求码,跟intent是 ...

  10. 从数据库中导出.csv文件

    需求: 本次将数据库中的数据导出成.csv文件(office可以打开), //数据的生成,根据你所选中的数据进行生成 //params:$activity_id -> 活动的id //param ...