黄季冬=>fox23

Freesc Huang
&
Windows Embedded
数据加载中……
[C# Tips] 有趣的类型静态构造器

这是C#中一个有趣的现象,也许您从中可以窥见些许CLR在构造类型时的行为,以及JIT编译的触发式编译过程。

看下面一段代码:

 1    class Program
 2    {
 3        static void Main()
 4        {
 5            myValueType1 type1 = new myValueType1();
 6            Console.WriteLine(myValueType1.myInt);
 7            Console.WriteLine("**********************");
 8            myValueType2 type2 = new myValueType2();
 9            type2.myInt = 123;
10            Console.WriteLine(type2.myInt);
11            Console.WriteLine("**********************");
12            myValueType3 type3 = new myValueType3();
13        }

14    }

15
16    struct myValueType1
17    {
18        static myValueType1()
19        {
20            Console.WriteLine("Hello from myValueType1");
21           // myInt = 111;
22        }

23        public static Int32 myInt;
24    }

25
26    struct myValueType2
27    {
28        static myValueType2()
29        {
30            Console.WriteLine("Hello from myValueType2");
31        }

32        public Int32 myInt;
33    }

34
35    struct myValueType3
36    {
37        static myValueType3()
38        {
39            Console.WriteLine("Hello from myValueType3");
40            myInt = 333;
41        }

42        public static Int32 myInt;
43    }

这里定义了三个结构:myValueType1,myValueType2,myValueType3。三个结构均带静态构造器,在构造器中都有一句用来输出的的代码。在myValueType1和myValueType3的静态。然后我们在main函数里面分别new 了相应的三个实例。您可以先想想输出的结果应该是怎样的。
 事实上您会得到如下的结果:


我们看到虽然三个结构中都有静态构造器,却只有第一个结构的被执行了。事实上,这个有趣的现象也是CLR对性能的考虑,除非类型确实被访问到了,否则永远不会调用到它的类型构造器,这个过程是JIT的。
当执行到第六行代码时,CLR尝试要去myValueType1查找静态字段myInt的值。这个时候,myValueType1才是真正被访问到了。静态构造器被执行,得到相应的输出。
而myValueType2中myInt是个实例成员,访问它的值只关系到实例type2实例。与类型本身没有任何关系,CLR不会执行类型myValueType2的静态构造器。
myValueType3跟myValueType11几乎是一样的,myInt是静态成员,但是在main函数中,myValueType3还是没有被真正访问到,只是利用它构造出了一个虚拟的对象结构,这种对象结构里面所有字段都被赋予一个0值或者null值
所以第二行输出为零
这些性质与JIT编译器都是分不开的。


posted on 2008-02-17 00:12 fox23 阅读(251) 评论(4)  编辑 收藏 所属分类: C#Thinkin' in CLR

评论

#1楼  2008-07-10 00:17 fuadam [未注册用户]

原来struct和class在静态构造上都是有区别的,学习了。

不知道博主是否了解静态字段在heap上的位置,我一直没找到确切的答案。
    回复  引用    

#2楼  2008-07-11 00:39 fuadam [未注册用户]

如果struct调用了自身的方法或者是覆写的基类方法也会出发调用静态构造,如果调用了没有覆写的方法比如ToString()就不会触发静态构造。不知何故
    回复  引用    

#3楼  2008-08-07 20:24 路西菲尔      

    回复  引用  查看    

#4楼 [楼主] 2008-08-07 21:09 fox23      

@路西菲尔
谢谢你的分享
    回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: