《Effective C#》读书笔记——条目13:正确地初始化静态成员变量<.NET资源管理>
我们知道在C#语言中创建一个类型的实例前,就应该初始化该类型的所有静态成员变量。C#语言为我们提供了静态初始化器和静态构造函数。其中,静态构造函数是一个特殊的构造函数,将在其他所有方法执行前以及变量或属性被第一次访问之前将自动调用静态构造函数,且仅执行一次。我们可以通过使用静态构造函数来初始化静态变量、实现单例模式或者执行类在可用之前的所有操作。但是不能够使用实例构造函数专门的私有函数或者其他什么方式来初始化静态变量。
静态类成员变量也有和实例成员类似的初始化器语法,如果只是需要为某个静态成员分配空间,可以直接使用初始化器语法,但是如果需要使用一些更复杂的逻辑来初始化静态成员变量那就应该直接使用静态构造函数。
1.单例模式中的静态构造函数
在C#中实现单例模式是静态构造函数的一个常见场景。只需要将实例构造函数声明为私有,然后添加一个初始化器即可:

public class Singleton
{
/// <summary>
/// 静态成员变量,添加 readonly 关键字
/// </summary>
private static readonly Singleton theOneAndOnly = new Singleton(); /// <summary>
/// 只读的静态属性
/// </summary>
public static Singleton TheOnly
{
get { return theOneAndOnly; }
} /// <summary>
/// 私有的实例构造函数
/// </summary>
private Singleton()
{
}
}

编译器生成的代码类似于下面:

public class Singleton
{
/// <summary>
/// 静态成员变量,添加 readonly 关键字
/// </summary>
private static readonly Singleton theOneAndOnly; /// <summary>
/// 只读的静态属性
/// </summary>
public static Singleton TheOnly
{
get { return theOneAndOnly; }
} /// <summary>
/// 静态构造函数
/// </summary>
static Singleton()
{
theOneAndOnly = new Singleton();
} /// <summary>
/// 私有的实例构造函数
/// </summary>
private Singleton()
{
}
}

和实例初始化器类似,静态初始化器在任何静态构造函数之前执行。而且,静态初始化器在调用基类的静态构造函数之前执行。
2.关于静态构造函数
静态构造函数用于初始化任何静态数据,在创建第一个实例或者引用任何静态成员之前,静态构造函数将会被CLR调用来初始化类,且仅调用一次。
静态构造函数具有如下特点:
- 静态构造函数既没有访问修饰符也不接受任何参数
- 在创建第一个实例或者引用任何静态成员之前,静态构造函数将会被CLR调用来初始化类
- 不能直接调用静态构造函数,并且在程序中不受控制
- 如果静态构造函数引发异常,CLR将不会尝试再次调用该构造函数,在应用程序作用域(AppDomain)内,类型将保持未初始化,这会导致该类及其派生类创建的类型没有得到完全初始化
3.静态初始化器&静态构造函数
通过前面关于静态构造函数的特点,我们知道:如果静态构造函数引发异常,在该次应用程序作用域(AppDomain)内CLR将不会尝试再次调用该构造函数,这会导致该类及其派生类创建的类型没有得到完全初始化。
如果直接只用静态初始化器语法:编译器会添直接将静态成员初始化代码加入到静态构造函数中,并且没有任何异常处理。所以在使用静态初始化器时,我们无法捕获并处理异常。然而在我们可以直接在静态构造函数中添加try/catch代码块了进行异常处理。如下:

public class Singleton
{
/// <summary>
/// 静态成员变量,添加 readonly 关键字
/// </summary>
private static readonly Singleton theOneAndOnly; /// <summary>
/// 只读的静态属性
/// </summary>
public static Singleton TheOnly
{
get { return theOneAndOnly; }
} /// <summary>
/// 直接在静态构造函数中进行异常处理
/// </summary>
static Singleton()
{
try
{
theOneAndOnly = new Singleton();
}
catch
{
//......
}
} /// <summary>
/// 私有的实例构造函数
/// </summary>
private Singleton()
{
}
}

小节:
静态初始化器和静态构造函数是初始化静态成员的最佳选择,容易理解并且不易出错。在其他语言中,这两个特性也是专门用来方便初始化静态成员而提供的。如果你需要在你的代码初始化静态成员的代码中进行异常处理是可以直接使用静态构造函数,在构造函数中添加异常处理代码;如果是只需要对静态成员进行空间的分配那么直接使用初始化器语法即可——在声明静态成员的时候对其进行初始化。
《Effective C#》读书笔记——条目13:正确地初始化静态成员变量<.NET资源管理>的更多相关文章
- Effective STL 读书笔记
Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...
- Effective STL读书笔记
Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按 ...
- Effective Java读书笔记完结啦
Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...
- effective c++读书笔记(一)
很早之前就听过这本书,找工作之前读一读.看了几页,个人感觉实在是生涩难懂,非常不符合中国人的思维方式.之前也有博主做过笔记,我来补充一些自己的理解. 我看有人记了笔记,还不错:http://www.3 ...
- 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化
Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...
- 《C#高效编程》读书笔记12-使用推荐成员初始化器而不是赋值语句
通常来说类都有不止一个构造函数.随着时间推移,成员变量的增加,构造函数的个数也会不断的增加.预防这种情况的最好方法是,在声明变量的时候就进行初始化,而不是在每个构造函数中进行. //初始化变量时声明 ...
- Effective C++读书笔记(转)
第一部分 让自己习惯C++ 条款01:视C++为一个语言联邦 一.要点 ■ c++高效编程守则视状况而变化,取决于你使用c++的哪一部分. 二.扩展 将c++视为一个由相关语言组成的联邦而非单一语言会 ...
- Effective java读书笔记
2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...
- Effective Objective-C 读书笔记
一本不错的书,给出了52条建议来优化程序的性能,对初学者有不错的指导作用,但是对高级阶段的程序员可能帮助不是很大.这里贴出部分笔记: 第2条: 使用#improt导入头文件会把头文件的内容全部暴露到目 ...
随机推荐
- postgresql数据库创建、修改、删除
一.数据库创建 语法: Command: CREATE DATABASEDescription: create a new databaseSyntax:CREATE DATABASE nam ...
- Oracle管理监控之段空间利用监控-oracle性能优化
SELECT S.OWNER, S.SEGMENT_NAME, S.SEGMENT_TYPE, S.PARTITION_NAME, ROUND(BYTE ...
- Oracle AWR之-enq: TX - allocate ITL entry
今天收到压力测试期间awr报告,测试人员要我看看数据库是否有可以优化的地方,数据库服务器配置信息:CPU:32*8,内存:480g 单实例数据库:oracle 11.2.0.4.具体分析过程如下: 可 ...
- Python开发【模块】:Pygal 绘制直方图
Pygal Pygal可用来生成可缩放的矢量图形文件,对于需要在尺寸不同的屏幕上显示的图表,这很有用,可以自动缩放,自适应观看者的屏幕 1.Pygal模块安装 ① Windows系统 # Pygal模 ...
- 主从同步DNS(BIND)
看着别人搭建很简单,其实到自己做的时候需要考虑更多的问题. 1.环境 1)操作系统最好一样,配置一样 2)关闭防火墙,selinux,时间要同步(我就是用的纽约的时区,同步中国的时间,虽然时间是相同的 ...
- 1 - bootstrap基本模板
bootstrap 3.x 下载地址:http://v3.bootcss.com/ 基本模板如下: <!DOCTYPE html> <html lang="zh-cn&qu ...
- 安装memcached扩展 验证过了可行
. 安装libmemached 复制代码 代码如下: wget https://launchpad.net/libmemcached/1.0/1.0.16/+download/libmemcached ...
- 【UI】android如何绘制一个饼图
代码下载 需求 1:实心饼图,颜色填充百分比区域 2:带区域说明 3:饼图有阴影 思路:这个其实和绘制进度条原理差不多,都是360度根据所占百分比算出绘制弧度,然后调用canvas的画弧函数. 阴影其 ...
- Entity Framework 并发处理(转)
什么是并发? 并发分悲观并发和乐观并发. 悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修 ...
- spring AOP的两种代理
本篇记录下spring AOP的两种代理,为下一篇AOP实现做下铺垫. 1.JDK动态代理 2.cglib代理 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP2.如果目标对象 ...