BeforeFieldInit的小叙
BeforeFieldInit是什么
上片的文章中我们看到了有静态构造函数,和没有静态构造函数,代码的执行顺序有着显著的区别。然后,我们反编译了下代码,发现了在类中有一个BeforeFieldInit特性,通过查各处资料,发现这是一个关于字段初始化时间的特性【提前初始化字段】,下面先来看一下这个特性在.net framework中的作用。摘取了别人的一份Demo:
class Foo
{
public static String x = GetStr("初始化 Foo 静态成员字段");
public static String GetStr(String str)
{
Console.WriteLine(str);
return str;
}
}
在上面Foo类中只定义了一个静态字段x和一个静态方法GetStr的方法,在这里需要关注的是静态字段x的初始化时机
static void Main(string[] args)
{
Console.WriteLine("Main方法开始");
Foo.GetStr("手动调用Foo.GetSring()方法");
String y = Foo.x;
}
可以看到静态成员字段的初始化是在最开始,我们将代码反编译IL后会发现在类中具有一个beforefieldinit特性
.class private auto ansi beforefieldinit BeoreFieldInitTest2.Foo
extends [mscorlib]System.Object
{
} // end of class BeoreFieldInitTest2.Foo
这里是对beforefieldinit的一个介绍 点我
如果想要取消BeofreFieldInit的话,可以显式的写静态构造函数
class Foo
{
public static string x = GetStr("初始化 Foo 静态成员字段");
//空的静态构造函数
static Foo(){}
public static String GetStr(String str)
{
Console.WriteLine(str);
return str;
}
}
结果如下:

.class private auto ansi BeoreFieldInitTest2.Foo
extends [mscorlib]System.Object
{
} // end of class BeoreFieldInitTest2.Foo
正如 别的园友告知,.NET Core中却有不一样的BeforeFieldInit
将最开始的代码在.NET Core中跑一跑会发现跟.NET Framework不一样的操作

那么在.NET Core加入静态构造函数?

可以看到.NET Core中加入静态构造函数以后输出跟.NET Framework一致
在.NET Framework中我们都是使用Lazy<>类来创建延迟加载单例,但是我们可以看到在.NET Core中beforefieldinit是延迟加载的,所以我们直接可以使用此方法来创建延迟安全单例
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main方法开始");
Foo.GetStr("手动调用Foo.GetSring()方法");
Console.WriteLine("我是分隔符");
Console.WriteLine("我是分隔符");
var foo= Foo.CreateInstance;
}
}
class Foo
{
public static Foo CreateInstance { get; } = new Foo();
private Foo()
{
Console.WriteLine("创建了Foo实例");
}
public static String GetStr(String str)
{
Console.WriteLine(str);
return str;
}
}
运行结果可以看到创建实例被延迟了

当然,这种创建单例也是有缺点的,当类中还有其它静态字段或属性时,并且在外部进行了调用,那么此时也会初始化此属性
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main方法开始");
Foo.GetStr("手动调用Foo.GetSring()方法");
var y = Foo.x;//调用静态字段/属性
Console.WriteLine("我是分隔符");
Console.WriteLine("我是分隔符");
var foo= Foo.CreateInstance;
}
}
class Foo
{
public static string x = GetStr("初始化 Foo 静态成员字段"); //加入了静态字段或属性
//public static String X { get; set; } = GetStr("初始化 Foo 静态成员字段");
public static Foo CreateInstance { get; } = new Foo();
private Foo()
{
Console.WriteLine("创建了Foo实例");
}
public static String GetStr(String str)
{
Console.WriteLine(str);
return str;
}
}

也就是说在.NET Core中beforfieldinit特性时当有一个静态变量被使用时就初始化所有静态变量
参考:https://www.cnblogs.com/yan7/p/9187874.html
BeforeFieldInit的小叙的更多相关文章
- 《java入门第一季》之类(String类常见方法小叙)
String类下面的构造方法和一些常见的方法: /* * 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,可以知道 * A:字符串字面值"abc&quo ...
- Asp.net 上传文件小叙(修改FileUpload显示文字等)
想要在asp.net网站上上传文件就得用到FileUpload,可是这个控件中“浏览”没法修改,可以使用html中<input type="file" 来解决该问题. 首先页 ...
- JBPM之JPdl小叙
JPdl:jbpm流程定义文件,下面是一个简单的流程定义文件: <?xml version="1.0" encoding="UTF-8"?> < ...
- C# 小叙 Encoding (一)
前言 众所周知计算机只能识别二进制数字,如1010,1001.我们屏幕所看到的文字,字符都是和二进制转换后的结果.将我们的文字按照某种规则转换二进制存储在计算机上,这一个过程叫字符编码,反之就是解码. ...
- 播放一个视频并用滚动条控制进度-OpenCV应用学习笔记二
今天我们来做个有趣的程序实现:利用OpenCV读取本地文件夹的视频文件,并且在窗口中创建拖动控制条来显示并且控制视频文件的读取进度. 此程序调试花费了笔者近一天时间,其实大体程序都已经很快写出,结果执 ...
- 用Django搭建个人博客—(3)
今日主题 定义博客文章和评论的的数据库定义 定义操作这几个Model的后台数据 User表 USER_STATUS = ( ('active', u'激活'), ('suspended', u'禁用' ...
- 数字图像处理(MATLAB版)学习笔记(2)——第2章 灰度变换与空间滤波
0.小叙闲言 1.本章整体结构 2.书中例子 例2.1 主要是使用函数imadjust,来熟悉一下灰度处理,体验一把 >> imread('myimage.jpg'); >> ...
- WPF自定义控件(2)——图表设计[1]
0.小叙闲言 除了仪表盘控件比较常用外,还有图表也经常使用,同样网上也有非常强大的图表控件,有收费的(DEVexpress),也有免费的.但我们平时在使用时,只想简单地绘一个图,控件库里面的许多功能我 ...
- WPF自定义控件(1)——仪表盘设计[1]
0.小叙闲言 又接手一个新的项目了,再来一次上位机开发.网上有很多控件库,做仪表盘(gauge)的也不少,功能也很强大,但是个人觉得库很臃肿,自己就计划动手来写一个控件库,一是为学习,二是为了项目.下 ...
随机推荐
- 洛谷——P1774 最接近神的人_NOI导刊2010提高(02)
https://www.luogu.org/problem/show?pid=1774 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古 ...
- PHP实现查询两个数组中不同元素的方法
以下实例讲述了PHP实现查询两个数组中不同元素的方法.分享给大家供大家参考,具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ...
- 【Codeforces Round #440 (Div. 2) C】 Maximum splitting
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 肯定用尽量多的4最好. 然后对4取模的结果 为0,1,2,3分类讨论即可 [代码] #include <bits/stdc++ ...
- 【Codeforces Round #437 (Div. 2) C】 Ordering Pizza
[链接]h在这里写链接 [题意] 给你参赛者的数量以及一个整数S表示每块披萨的片数. 每个参数者有3个参数,si,ai,bi; 表示第i个参赛者它要吃的披萨的片数,以及吃一片第 ...
- Spring 使用Cache(转)
从3.1开始Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事物管理的支持.Spring Cache是作用在方法上的,其核心思想是:当我们在调用一个缓存方法时会把该方法参数 ...
- IOS RGB颜色转换
- (UIColor *)getColor:(NSString *)hexColor { unsigned int red,green,blue; NSRange range; range.lengt ...
- [RxJS] ReplaySubject with buffer
A BehaviorSubject can remember the latest value emitted, but what if we wanted Observer B to see all ...
- PHP通用非法字符检测函数集锦
<? // [变量定义规则]:‘C_’=字符型,‘I_’=整型,‘N_’=数字型,‘L_’=布尔型,‘A_’=数组型 // ※CheckMoney($C_Money) 检查数据是否是 99999 ...
- VC/MFC中为程序定义全局快捷键
VC 2010-05-01 18:01:34 阅读287 评论0 字号:大中小 订阅 1.注册快捷键 在初始化函数,如OnInitDialog() 注册快捷键,代码如下: #define HotKey ...
- Android——WebView方式开发web App
昨天接到个酬劳丰厚的任务.把java新生系统做成webApp,想想蛮简单的.所以当时就装作非常为难的样子答应了. 所谓Web App,用曾经我那个老PM的话来说.就是在壳里面套上页面.这里的壳相当于浏 ...