《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导入头文件会把头文件的内容全部暴露到目 ...
随机推荐
- C#6.0语法特性
1.自动属性初始化的改进(有用) 原来的用法(声明时无法同时初始化),例如: class MyClass { public int Age { get; set; } public string Na ...
- CH0601 Genius ACM【倍增】【归并排序】
0601 Genius ACM 0x00「基本算法」例题 描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数 ...
- New动态分配 Delete 释放内存
在C++中,对于变量和对象都是编译器在编译时分配好的,对于数组初始化时,无法确定多少内存,很容意造成大开小用的情况. new 动态分配 一般格式:1. 指针变量名 =new 类型标识符; 2.指针 ...
- sailsjs入门到精通(一)
sailsjs 官方网站http://sailsjs.com/ 中文网站: http://sailsdoc.swift.ren/ 1 全局安装sails npm install sails@bet ...
- python 定义类 学习1
此时的d1就是类Dog的实例化对象 实例化,其实就是以Dog类为模版,在内存里开辟一块空间,存上数据,赋值成一个变量名 # 定义类模板 class dog(object): # 定义类的方法功能 # ...
- 认识与设计Serverless(一)
一.什么是Serverless 定义:Serverless是一种无服务器的架构,区别于传统的Baas,SAAS,作为FAAS(函数即服务)而存在,函数由事件驱动触发并按需调用. 按需调用:区别于传统的 ...
- Jitamin
安装环境要求 PHP 5.6或更高(推荐使用PHP7) 数据库, 推荐使用MySQL 或 PostgreSQL. 当然SQLite也可以运行. Composer 安装手册 一. 克隆代码 假设我们把j ...
- maven运行junit用例并生成报告
原文地址https://blog.csdn.net/hdyrz/article/details/78398964 测试类如下: [java] view plain copypackage com.mm ...
- 安装WIN7时提示“缺少所需的CD/DVD驱动器设备驱动程序”
同事机器重装Win7,先百度了一下不适合64bit,于是直接上32bit系统. BOIS设置DVD启动,把安装盘放在移动光驱里,开始安装. 在安装时出现下图错误:“缺少所需的CD/DVD驱动器设备驱动 ...
- Python 开发工具和框架安装
引言: 其实之前对于 Python,只是知道有这门语言而已.大部分还是使用 .net 开发的,之前也学了 MVC+EF 开发,但是由于工作上完全用不到,也就没有在博客记录学习的东西了. 最近又接触到了 ...