其实,作为C#程序员,我们看到这样的题目,也许没什么感觉,因为我们每天都在对C#对象实例化,但是,我们真的知道实例化的过程吗?
也许,我们总是习惯于写这样的语句 A a=new A();,可是,我们真的知道这样一句话到底是怎么样执行的吗?
我想,大多数程序员并不清楚。那么今天,我们通过一个例子来探究一下类的实例化过程。
public class ConsoleTest
{
public ConsoleTest(string content)
{
Console.WriteLine(content);
}
}
public class BaseOne
{
static ConsoleTest a2 = new ConsoleTest("a2");
ConsoleTest a3 = new ConsoleTest("a3");
static BaseOne()
{
ConsoleTest a1 = new ConsoleTest("a1");
}
public BaseOne()
{
ConsoleTest a4 = new ConsoleTest("a4");
}
public virtual void MyFunction()
{
ConsoleTest a5 = new ConsoleTest("a5");
}
public virtual void MyFunction2()
{
ConsoleTest a6=new ConsoleTest("a6");
}
}
public class BaseTwo : BaseOne
{
static ConsoleTest BaseTwo2 = new ConsoleTest("b2");
ConsoleTest BaseTwo3 = new ConsoleTest("b3");
static BaseTwo()
{
ConsoleTest b1 = new ConsoleTest("b1");
}
public BaseTwo()
{
ConsoleTest b4 = new ConsoleTest("b4");
}
public override void MyFunction()
{
ConsoleTest b5 = new ConsoleTest("b5");
}
public new void MyFunction2()
{
ConsoleTest b6 = new ConsoleTest("b6");
}
}
class Program
{
static void Main(string[] args)
{
BaseTwo b = new BaseTwo();
b.MyFunction();
b.MyFunction2();
BaseOne a = new BaseTwo();
a.MyFunction();
a.MyFunction2();
Console.ReadKey();
}
}
执行结果是什么?
这段代码顺便考察了一下 new 与override 关键字的区别。
执行结果如下:
b2
b1
b3
a2
a1
a3
a4
b4
b5
b6
b3
a3
a4
b4
b5
a6
-------------------------------------------------------------------------------
以上是程序执行结果,看到这里,大家比照一下自己的答案,答对了吗?
呵呵,我第一次回答,是没答对。由此我知道,很多时候,我们只会用,但是不知道原理细节。
我这么说并不是说做什么事情都要把细节摸透,这是因地制宜的。
我们掌握了类的实例化过程,那么就可以提高我们编写代码的质量,提高程序的运行性能。
有的时候,知其所以然会更利于我们写出高质量的程序。
--------------------------------------------------------------------------------
哈哈不多说废话了,下面解释一下上面执行的顺序。
首先,子类实例化,如果是第一次实例化,那么首先实例化静态成员字段,其次调用静态构造函数;如果不是第一次实例化,那么这一步跳过。
其次,子类实例化非静态成员字段。
再者,父类实例化,如果是第一次实例化,那么首先实例化父类静态成员字段,其次调用父类静态构造函数;如果不是第一次实例化,那么这一步跳过。
接着,父类实例化非静态成员字段。
然后,父类调用父类非静态构造方法。
紧跟着,子类调用子类非静态构造方法。
---------------------------------------------------------------------------------
以上就是类的实例化过程,有一点大家也许会疑惑,那就是静态构造函数,与静态成员变量。
每一个类都有一个静态构造函数, 该静态构造函数在实例化类的第一个对象的时候被调用,而且只调用一次。
静态成员变量的实例化是在调用静态构造函数之前,也是实例化一次。