最后的据点

Think it,Plan it,Build it,Make it,Happy it,Enjoy it! 格物,诚意,志存高远,脚踏实地,让精益求精成为习惯!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

静态构造函数

Posted on 2009-06-22 18:42  最后的据点  阅读(296)  评论(0编辑  收藏  举报

静态构造函数用于初始化任何静态数据,或用于执行仅需执行一次的特定操作。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。

静态构造函数具有以下特点:

  • 静态构造函数既没有访问修饰符,也没有参数。

  • 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。

  • 无法直接调用静态构造函数。

  • 在程序中,用户无法控制何时执行静态构造函数。

  • 静态构造函数的典型用途是:当类使用日志文件时,将使用这种构造函数向日志文件中写入项。

  • 静态构造函数在为非托管代码创建包装类时也很有用,此时该构造函数可以调用 LoadLibrary 方法。

  • 如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数。

  • 如果类中包含用来开始执行的 Main 方法,则该类的静态构造函数将在调用 Main 方法之前执行。

  • 如果类中的静态字段带有初始化,则静态字段的初始化语句将在静态构造函数之前运行。

示例:

在此示例中,类 Bus 有一个静态构造函数和一个静态成员 Drive()。当调用 Drive() 时,将调用静态构造函数来初始化类。

public class Bus
{
    // Static constructor:
    static Bus()
    {
        System.Console.WriteLine("The static constructor invoked.");
    }
 
    public static void Drive()
    {
        System.Console.WriteLine("The Drive method invoked.");
    }
}
 
class TestBus
{
    static void Main()
    {
        Bus.Drive();
    }
}

我们再来看另外一个例子:

 

using System;
class A
{
    public static int X;
    static A()             // 步骤1
    {
        X = B.Y + 1;  //此时B.Y为0
        Console.WriteLine("static A()");
    }
}
class B
{
    public static int Y = A.X + 1;      // 步骤0  
    static B()                          //步骤2
    {
        Console.WriteLine("static B()");
    }
    static void Main()         
    {
        Console.WriteLine("X = {0}, Y = {1}", A.X, B.Y);  //步骤3
        Console.ReadLine();
    }
}

 

运行的结果是:

static A()

static B()

X=1,Y=2

关键是它的执行顺序。

另外下面的一段话也值得思考:

实际上,CLR保证在类的其它操作之前(不包括静态字段的初始化语句)运行静态构造方法。但是,它只保证启动静态构造方法,实际上不保证它的运行结束。因此,可以人为的制造出一种病态情况,两个类互相具有循环依赖关系。这时,CLR会在不同的线程中运行静态构造方法(发现要跑的相应的静态构造函数的线程已经在跑了,则不再发起新线程),以兑现至少以正确的顺序启动两个静态构造方法的最低保证,不会出现死锁。