当前位置: 移动技术网 > IT编程>开发语言>c# > C#小知识之有趣的类型静态构造器

C#小知识之有趣的类型静态构造器

2019年07月18日  | 移动技术网IT编程  | 我要评论

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

看下面一段代码:

复制代码 代码如下:

class program
    {
        static void main()
        {
            myvaluetype1 type1 = new myvaluetype1();
            console.writeline(myvaluetype1.myint);
            console.writeline("**********************");
            myvaluetype2 type2 = new myvaluetype2();
            type2.myint =23;
            console.writeline(type2.myint);
            console.writeline("**********************");
            myvaluetype3 type3 = new myvaluetype3();
        }
    }

    struct myvaluetype1
    {
        static myvaluetype1()
        {
            console.writeline("hello from myvaluetype1");
           // myint = 111;
        }
        public static int32 myint;
    }

    struct myvaluetype2
    {
        static myvaluetype2()
        {
            console.writeline("hello from myvaluetype2");
        }
        public int32 myint;
    }

    struct myvaluetype3
    {
        static myvaluetype3()
        {
            console.writeline("hello from myvaluetype3");
            myint = 333;
        }
        public static int32 myint;
    }

这里定义了三个结构: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编译器都是分不开的。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网