Static 变量对于单例对象,几乎是固定的用法,很多人说Static变量是在程序执行的时候,直接加载的,我对这个问题抱有一个怀疑态度,我做了一个小测试,来试验一下这块内容。
代码如下:
static void Main(string[] args)
{
Console.WriteLine("Main start");
Task.Run(() =>
{
var ins = StaticInstance.Instance;
Console.WriteLine(ins.GetHashCode());
});
Task.Run(() =>
{
var ins = StaticInstance.Instance;
Console.WriteLine(ins.GetHashCode());
});
Console.ReadLine();
}
public class StaticInstance
{
public static StaticInstance Instance { get; } = new StaticInstance();
static StaticInstance(){
Console.WriteLine("Static Constructor Work");
}
private StaticInstance()
{
Console.WriteLine("Constructor Work");
}
public static void Hello()
{
Console.WriteLine("Hello, this is StaticInstance Class");
}
}
进入Main方法的时候,打印了进入的消息,然后调用了instance单例对象,结果打印的输出结果是
Main start
Constructor Work
Static Constructor Work
63835064
63835064
所以得到了第一部分结论,对于静态标记的属性和方法,加载的顺序是:
- 静态变量
- 静态构造器
而且是只有用到Static变量的时候,才会加载,也就是说,如果你的程序有大量没有用到的单例对象,那他们不会被加载到内存
这里在修改一下Main方法,如果我不调用单例属性,只调用一个类的static方法,会怎么样,修改的代码如下:
static void Main(string[] args)
{
Console.WriteLine("Main start");
Task.Run(() =>
{
StaticInstance.Hello();
});
Task.Run(() =>
{
StaticInstance.Hello();
});
Console.ReadLine();
}
执行后的结果是:
Main start
Constructor Work
Static Constructor Work
Hello, this is StaticInstance Class
Hello, this is StaticInstance Class
发现单例对象依然是被创建出来了。
所以我个人认为:
- 静态成员和构造器,在类调用的过程才会加载,并不是在程序进入的时候加载的
- 对于类的调用,不论是实例化方法,还是静态方法,调用的这个时候,虚拟机才会去加载类的信息到栈区,才会产生这样的现象,所以也是一个惰性加载的过程。
以上是关于Static变量的一些小Tips,希望对你有所帮助,如果不对,也欢迎批评指正。