Effective C# 原则13:用静态构造函数初始化类的静态成员
Item 13: Initialize Static Class Members with Static Constructors
(译注:initializer在上文中译为了“初始化器”,实在不好听,本文中全部改译为:“预置方法”)
你应该知道,在一个类型的任何实例初始化以前,你应该初始化它的静态成员变量。在里C#你可以使用静态的预置方法和静态构造函数来实现这个目的。一个类的静态构造函数是一个与众不同的,它在所有的方法,变量或者属性访问前被执行。你可以用这个函数来初始化静态成员变量,强制使用单件模式,或者实现其它任何在类型的实例可用前应该完成的工作。你不能用任何的实例构造函数,其它特殊的私有函数, 或者任何其它习惯方法来初始化一个 变量(译注:编译器就不让你这样做,所以你不用担心这样的问题)。

和实例的预置方法一样,你可以把静态的预置方法做为静态构造函数可替代的选择。如果须要简单的分配一个静态成员,就直接使用初始化语法。当你有更复杂的逻辑来初始化静态成员变量时,就创建一个静态构造函数:

public class MySingleton
{
  private static readonly MySingleton _theOneAndOnly =
    new MySingleton( );

public static MySingleton TheOnly
  {
    get
    {
      return _theOneAndOnly;
    }
  }

private MySingleton( )
  {
  }

// remainder elided
}

可以用下面的方法简单的实现单件模式,实际上你在初始化一个单件模式时可能有更复杂的逻辑:
public class MySingleton
{
  private static readonly MySingleton _theOneAndOnly;

static MySingleton( )
  {
    _theOneAndOnly = new MySingleton( );
  }

public static MySingleton TheOnly
  {
    get
    {
      return _theOneAndOnly;
    }
  }

private MySingleton( )
  {
  }

// remainder elided
}

同样,和实例的预置方法一样,静态的预置方法在静态的构造函数调用前执行。并且,你的静态预置方法在基类的静态构造函数执行前被执行。

当应用程序第一次装载你的数据类型时,CLR自动调用静态构造函数。你只能定义一个静态构造函数,并且不能有参数。因为静态构造函数是CLR调用的,你必须十分注意异常的产生。如果在静态构造函数里产生了异常,CLR将会直接终止你的应用程序。正因为异常,静态构造函数常常代替静态预置方法。如果你使用静态预置方法,你自己不能捕获异常。做为一个静态的构造,你可以这样(参见原则45):
static MySingleton( )
{
  try {
    _theOneAndOnly = new MySingleton( );
  } catch
  {
    // Attempt recovery here.
  }
}

静态预置方法和静态构造函数为你的类提供了最清爽的方法来初始化静态成员。与其它语言不同,它们被添加到C#语言中,是初始化静态成员的两个不同的特殊位置。

===================

Item 13: Initialize Static Class Members with Static Constructors
You know that you should initialize static member variables in a type before you create any instances of that type. C# lets you use static initializers and a static constructor for this purpose. A static constructor is a special function that executes before any other methods, variables, or properties defined in that class are accessed. You use this function to initialize static variables, enforce the singleton pattern, or perform any other necessary work before a class is usable. You should not use your instance constructors, some special private function, or any other idiom to initialize static variables.

As with instance initialization, you can use the initializer syntax as an alternative to the static constructor. If you simply need to allocate a static member, use the initializer syntax. When you have more complicated logic to initialize static member variables, create a static constructor.

Implementing the singleton pattern in C# is the most frequent use of a static constructor. Make your instance constructor private, and add an initializer:

public class MySingleton
{
  private static readonly MySingleton _theOneAndOnly =
    new MySingleton( );

public static MySingleton TheOnly
  {
    get
    {
      return _theOneAndOnly;
    }
  }

private MySingleton( )
  {
  }

// remainder elided
}

The singleton pattern can just as easily be written this way, in case you have more complicated logic to initialize the singleton:

public class MySingleton
{
  private static readonly MySingleton _theOneAndOnly;

static MySingleton( )
  {
    _theOneAndOnly = new MySingleton( );
  }

public static MySingleton TheOnly
  {
    get
    {
      return _theOneAndOnly;
    }
  }

private MySingleton( )
  {
  }

// remainder elided
}

As with instance initializers, the static initializers are called before any static constructors are called. And, yes, your static initializers execute before the base class's static constructor.

The CLR calls your static constructor automatically when your type is first loaded into an application space. You can define only one static constructor, and it must not take any arguments. Because static constructors are called by the CLR, you must be careful about exceptions generated in them. If you let an exception escape a static constructor, the CLR will terminate your program. Exceptions are the most common reason to use the static constructor instead of static initializers. If you use static initializers, you cannot catch the exceptions yourself. With a static constructor, you can (see Item 45):

static MySingleton( )
{
  try {
    _theOneAndOnly = new MySingleton( );
  } catch
  {
    // Attempt recovery here.
  }
}

Static initializers and static constructors provide the cleanest, clearest way to initialize static members of your class. They are easy to read and easy to get correct. They were added to the language to specifically address the difficulties involved with initializing static members in other languages.

转载于:https://www.cnblogs.com/WuCountry/archive/2007/03/02/662095.html

Effective C# 原则13:用静态构造函数初始化类的静态成员(译)相关推荐

  1. Effective C# 原则18:实现标准的处理(Dispose)模式(译)

    Effective C# 原则18:实现标准的处理(Dispose)模式 我们已经讨论过,处理一个占用了非托管资源对象是很重要的.现在是时候来讨论如何写代码来管理这些类占用的非内存资源了.一个标准的模 ...

  2. Effective C# 原则48:了解更多的工具和资源(译)

    Effective C# 原则48:了解更多的工具和资源   Item 48: Learn About Tools and Resources 对于C#以及.Net来说这是激动人心的时候.这些工具目前 ...

  3. 朋友面试被问到---静态构造函数

    朋友面试被问到---静态构造函数 原文:朋友面试被问到---静态构造函数 事情是这样的 朋友是一个一年多经验的.Net开发人员 在面试新公司的时候,被面试官问到什么是"静态构造函数" ...

  4. 由单例模式学到:静态构造函数和静态字段

    编译器在编译的时候,会事先分析所需要的静态字段,如果这些静态字段所在的类有静态的构造函数,则忽略静态字段的初始化,否则先进行静态字段的初始化.对类的静态成员初始化的顺序取决于在Main函数中的引用顺序 ...

  5. c#只读字段和常量的区别,以及静态构造函数的使用 .

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  6. C#中静态构造函数的一些理解

    首先,先看一张结论表 If(有类显式静态构造函数) { If(有访问静态成员) { 在进入Main函数之后,第一次访问静态成员之前,先调用静态构造函数,以后将不再调用静态构造函数,同一个静态构造函数最 ...

  7. 静态构造函数和静态成员变量初始化的调用时间

        class Class1     {         [STAThread]         static void Main(string[] args)         {         ...

  8. 《Effective C#》Item 14:使用构造函数初始化语句

    在写程序的时候,往往会出现为一个类型提供不同场景的构造函数,可能大多构造函数比较相似,而C#中又不允许缺省参数,因此构造函数的编写无疑是一个重复工作.但是使用Copy和Paste来完成构造函数的编写, ...

  9. WIN7 UAC/结构体的Equals方法/C# 开发wince程序,窗口上总留有一块空白区域/静态构造函数...

    1. vs2005在win7下通过IIS7调试时,调用dll失败,但在XP下正常.相信是权限问题,请问应该如何解决?能不能设置dll默认以管理员身分运行? 备注:此DLL已注册成功! 回复引用 全部回 ...

最新文章

  1. 机器学习(MACHINE LEARNING)使用ARIMA进行时间序列预测
  2. JQuery变量数字相加的研究
  3. (教学思路 C#集合二)哈希表
  4. Mybatisplus 自动生成字段 强制覆盖 null或者空字符串也覆盖
  5. vue-cli多环境配置
  6. Linux 实操 —— 日志筛选操作(sed与wc命令介绍)
  7. 网上读书关于软件测试,【读书笔记】之软件测试
  8. linux修改语言环境
  9. 《JQuery 能干点啥~》第8讲 XPath选择器
  10. Docker 基本操作
  11. Facebook vs Chrome 关公秦琼的未来之战,互联网营销
  12. java完整分页算法,最简单的java分页算法
  13. 怎么用计算机按键弹歌谱,键盘钢琴及谱子(弹钢琴练打字一举两得)
  14. linux下安装postgresql遇到的问题(zlib library not found,readline library not found)
  15. 用产品思维设计API(二)——数据解耦,才是前后分离的本质
  16. android 定时器 误差,运动会计时器(PC+安卓)版本
  17. Windows学习总结(1)——win10系统最新快捷键汇总
  18. 软件测试的简单理解以及与软件开发的区别
  19. chartengine 图表的应用流程
  20. Maven实战读书笔记1

热门文章

  1. 还在做Excel分析师?HR:对不起,我们还要求会Python!
  2. 如果重走职场,一定会送自己 8 个锦囊
  3. 在SQL 2005中用T-SQL插入中文数据时出现的问号或乱码的解决方案[转]
  4. 三星全球首家量产18nm DRAM
  5. jquery等待特定元素加载再执行相关函数
  6. Dockerfile实践优化建议
  7. hibernate与mybatis的区别和应用场景
  8. 正式迁移博客到osc
  9. loadrunner中自定义查找并替换函数
  10. 在Linux和Windows操作系统中socket program的兼容问题