本文是为了说明在C#中静态成员的调用与初始化问题,仅供大家参考。
先从一个简单的小程序开始:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace teststatic
{
class A{
public static int i;
static A()
{
Console.WriteLine("static statement in A");
}
public A()
{
Console.WriteLine("construction A");
}
~A()
{
Console.WriteLine("destroy instance by ~A()");
}
}
class B
{
public static int i;
public A a = new A();
static B()
{
Console.WriteLine("static statement in B");
A.i++;
}
public B()
{
Console.WriteLine("construction B");
}
~B()
{
Console.WriteLine("destroy instance by ~B()");
}
}
class C
{
public B b;
static C()
{
Console.WriteLine("static construction in C");
A.i++;
B.i++;
}
public C()
{
Console.WriteLine("construction in class C");
b = new B();
}
~C()
{
Console.WriteLine("destroy instance by ~C()");
}
public static void Main(string[] args)
{
Console.WriteLine("main in class C");
B.i++;
A.i++;
C c = new C();
Console.WriteLine("int put a string :");
string s = Console.ReadLine();
Console.WriteLine("begin GC");
GC.Collect();
Thread.Sleep(2000);
Console.WriteLine("end GC");
Console.WriteLine("int put a string :");
s = Console.ReadLine();
Console.WriteLine("A.i = "+A.i+"/t B.i = "+B.i);
}
}
}
static construction in C
static statement in A
static statement in B
main in class C
construction in class C
construction A
construction B
int put a string :
a
begin GC
end GC
int put a string :
b
A.i = 3 B.i = 2
destroy instance by ~A()
destroy instance by ~B()
destroy instance by ~C()
続行するには何かキーを押してください . . .
以上结果证明:
1,类C中有B的一个对象作为成员变量,当实例化C的时侯,B先被实例化
2,消毁一个C的对象的时侯,先调用作为成员变量的B的析构函数,再调用C的析构函数
为了测试静态成员是在类加载的时侯初始化的又做一测试程序:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace teststatic
{
class A{
public static int i;
static A()
{
Console.WriteLine("static statement in A");
}
public A()
{
Console.WriteLine("construction A");
}
~A()
{
Console.WriteLine("destroy instance by ~A()");
}
}
class B
{
public static int i;
// public A a = new A();
static B()
{
Console.WriteLine("static statement in B");
}
public B()
{
Console.WriteLine("construction B");
}
~B()
{
Console.WriteLine("destroy instance by ~B()");
}
}
class C
{
// public B b;
static C()
{
Console.WriteLine("static construction in C");
}
public C()
{
Console.WriteLine("construction in class C");
// b = new B();
}
~C()
{
Console.WriteLine("destroy instance by ~C()");
}
public static void Main(string[] args)
{
Console.WriteLine("main in class C");
B.i++;
A.i++;
// C c = new C();
Console.WriteLine("int put a string :");
string s = Console.ReadLine();
Console.WriteLine("begin GC");
GC.Collect();
Thread.Sleep(2000);
Console.WriteLine("end GC");
Console.WriteLine("int put a string :");
s = Console.ReadLine();
Console.WriteLine("A.i = "+A.i+"/t B.i = "+B.i);
}
}
}
运行结果如下:
static construction in C
main in class C
static statement in B
static statement in A
int put a string :
d
begin GC
end GC
int put a string :
d
A.i = 1 B.i = 1
続行するには何かキーを押してください . . .
此结果证明,静态成员和静态构造函数是在类加载的时侯调用的。那么什么时侯才加载类呢?
目前我只知道三种:
1, 当new 一个类的对象的时侯
2, 类名.成员调用类的静态成员的时侯
3, 创建类的子类的时侯
最后有一个问题:类的静态成员变量是在什么时侯被GC回收的呢?
本人理解是在进程结束的时侯,不是类的对象被回收的时侯。因为当一个类没有实例化的时侯也能调用它的静态成员变量。
本人正在学习中,希望各位指正.