静态变量
用static关键字修饰的变量,他是属于类的,全局可以共享,可看成Application级的变量,它在类被实例化或调用类的其它静态成员时初始化,并且只被初始化一次。在使用静态变量的时候,要注意串值的情况。以前有碰到过一个winform程序,用静态变量保存从配置文件中读取的值(刚开始不知是用静态变量存储的),应需求变动,我改了配置文件中的值,没有重启应用,结果可想而知(因没有达到业务人员的预期效果,把我一顿说),后来回去看代码,才发现静态变量这个问题(虽然不是我写的,我也不该偷懒不重启应用)。
静态属性
静态属性不属于任何实例,也是属于类的,和静态变量不同的是,只用在调用它的时候,才会初始化,而且每次调用都会重新赋值。
静态构造函数
静态构造函数需用static修饰,但不能用public或private等关键字修饰,因为静态构造函数不能直接调用,无论是直接实例化还是通过Class.Method的方式。
下面我们看看在类中,静态变量和静态构造函数的初始化顺序是怎样的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyTest01
{
public class MyClassA
{
public static int x = 0;
public int y = 1;
public static string ClassNm
{
get
{
return typeof(MyClassA).ToString();
}
}
static MyClassA()
{
x = 1;
}
public MyClassA()
{
}
}
}
当实例化MyClassA时,通过断点,得到如下图结果
从而可以得知初始化的顺序为:静态变量->静态构造函数>普通变量->构造函数,因为没有用到静态属性,这里并没有初始化。
再来看一个经典例子
`using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyTest01
{
public class A
{
public static int x;
static A()
{
x = B.y + 1;
Console.WriteLine("static A()");
}
}
public class B
{
public static int y = A.x + 1;
static B()
{
Console.WriteLine("static B()");
}
static void Main(string[] args)
{
Console.WriteLine("y = {0},x = {1}", B.y, A.x);
Console.ReadLine();
}
}
}
`
运行结果:
因为启动的Main函数在B类中,所以启动时会先进入B,按上面的执行顺序,会先去初始化静态变量y,这里会先默认给y一个初始值0,由于赋值的代码中又调用了A类的静态变量x,因而进入到A类中,先初始化x=0,再执行A类的静态构造函数,得到x=1(因为y已经有默认初始值0),然后跳回到B中y的赋值语句,得到y=2。
这里需要注意的是:main函数在哪个类,就先初始化哪个类的静态变量,如果main函数在两个类的外部,就是先用到谁,谁先初始化。然后静态变量初始化都是先默认给一个初始值再执行赋值操作,如static int a=1,实际可看成a=0,a=1;
好了,能力有限,如有问题,欢迎指正。