我们知道在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()
{
}
}

小节:

  静态初始化器和静态构造函数是初始化静态成员的最佳选择,容易理解并且不易出错。在其他语言中,这两个特性也是专门用来方便初始化静态成员而提供的。如果你需要在你的代码初始化静态成员的代码中进行异常处理是可以直接使用静态构造函数,在构造函数中添加异常处理代码;如果是只需要对静态成员进行空间的分配那么直接使用初始化器语法即可——在声明静态成员的时候对其进行初始化。

最新文章

  1. js api 实现钉钉免登
  2. 在android用Get方式发送http请求
  3. Terminal中输入命令直接打开QtCreator,以及创建其桌面快捷方式
  4. Android开发之 adb 启动问题或是部署应用不成功,出现“The connection to adb is down, and a severe error has occured.”错误
  5. .NET: WPF Data Binding
  6. html,body最顶层元素.
  7. vmware workstation 10.0
  8. Java ftp断点续传
  9. JS动画理论
  10. NSLog( @&quot;%@&quot;, i );
  11. reload(sys)后print失效问题解决
  12. Tortoisegit图文使用教程
  13. 【php】记录一次生产环境bug的调试
  14. Paired t-test
  15. bzoj1007/luogu3194 水平可见直线 (单调栈)
  16. POJ 2387 Til the Cows Come Home (图论,最短路径)
  17. Git Note
  18. poj3080kmp或者暴力
  19. 温故而知新复习下PHP面向对象
  20. [转帖]“剖开” LinuxONE 和 Exadata,架构专家解读里面到底有什么

热门文章

  1. 用到了yii2 hasMany() 方法,一对多关联
  2. Google Now &#39;not available in your country&#39;
  3. Ubuntu下MySQL主从同步配置
  4. rac库grid目录权限(6751)导致数据库宕机案例 此方法仅用于紧急救助
  5. Grafana+Prometheus监控
  6. ansible相关
  7. JavaScript高级程序设计第三版学习笔记(一)之数据类型区分详谈
  8. 关于volatile 最完整的一篇文章
  9. mysql 数据操作 单表查询 group by 练习
  10. [py]django的manytomany字段和后台搜索过滤功能