加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

关于Type Initializer和 BeforeFieldInit的问题,看看大家能否给

发布时间:2020-12-16 09:05:07 所属栏目:asp.Net 来源:网络整理
导读:下面通过一个简单的Console Application演示Type Innitializer的执行顺序。希望大家各抒己见,对于实验的结果给出一个圆满的解释,同时希望读者从中理解到更多关于编译、关于CLR一些被我们忽略的细节。 代码如下,在类Foo中定义了两个static成员:静态字段Fi

下面通过一个简单的Console Application演示Type Innitializer的执行顺序。希望大家各抒己见,对于实验的结果给出一个圆满的解释,同时希望读者从中理解到更多关于编译、关于CLR一些被我们忽略的细节。

代码如下,在类Foo中定义了两个static成员:静态字段Field和静态方法GetString,Field通过于Inline的方式通过调用GetString进行初始化。在Main()中仅仅两行代码:Console.WriteLine("Start ...");Foo.GetString("Manually invoke the static GetString() method!");?

   1: using System;
   3: {
   5:     {
   7:         {
   9:             Foo.GetString("Manually invoke the static GetString() method!");
  11:     }
  13:     class Foo
  15:         public string Field = GetString("Initialize the static field!");
  17:         string GetString(string s)
  19:             Console.WriteLine(s);
  21:         }
  23: } 

对于结果,我想很多人都能够猜得到,如果在显示调用GetString()之前,需要完成静态成员的初始化,所以最终的输出结果如下图所示:

然后我们在Main()种多加一行代码:string field = Foo.Field; 也就是获取Foo的静态字段:

2: {
   4:     Foo.GetString("Manually invoke the static GetString() method!");
   6: }

最终的输出结果就和上面不一样了,静态字段的初始化工作居然提前了(在Console.WriteLine("Start ...");之前执行)

“神奇”的事情还没有结束,如果我们在Foo中加上一个静态构造函数,其中不执行任何的操作:

static Foo()
   7:? 
   9:     {
  11:         return s;
  13: }

再来看看现在执行结果,又和先前的一样的了。

?
我先不做任何评论(因为我也不太确定我的认识就是正确的),看看大家对此有什么看法。

再添加另一个static constructor的例子,较之上面一个要简单点。在Bar继承自基类Foo,在Foo和Bar均定义了静态构造函数。静态方法DoSomething()定义在Foo中,在Main()中却通过Bar.DoSomething();进行调用。

9: }
  11:? 
  13:     {
  15:         {
  17:         }
  19:         void DoSomething()
  21:             Console.WriteLine("Done ...");
  23:     }
  25:     class Bar : Foo
  27:         static Bar()
  29:             Console.WriteLine("static Bar() is invoked");
  31:     }