C#中的基本构造函数-首先调用哪个?
哪个首先被称为基本构造函数或者"此处的其他内容"?
public class MyExceptionClass : Exception { public MyExceptionClass(string message, string extrainfo) : base(message) { //other stuff here } }
解决方案
我说基地
编辑请参阅:
http://www.c-sharpcorner.com/UploadFile/rajeshvs/ConsNDestructorsInCS11122005010300AM/ConsNDestructorsInCS.aspx
那里说:
using System; class Base { public Base() { Console.WriteLine("BASE 1"); } public Base(int x) { Console.WriteLine("BASE 2"); } } class Derived : Base { public Derived():base(10) { Console.WriteLine("DERIVED CLASS"); } } class MyClient { public static void Main() { Derived d1 = new Derived(); } }
This program outputs BASE2 DERIVED CLASS
基本构造函数将首先被调用。
试试吧:
public class MyBase { public MyBase() { Console.WriteLine("MyBase"); } } public class MyDerived : MyBase { public MyDerived():base() { Console.WriteLine("MyDerived"); } }
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=777
首先调用基础构造函数。
将调用Exception构造函数,然后将调用Child类构造函数。
简单的OO原理
在这里看看
http://www.dotnet-news.com/lien.aspx?ID=35151
实际上,派生类构造函数首先执行,但是Ccompiler插入对基类构造函数的调用,作为派生构造函数的第一条语句。
因此:首先执行了派生,但是"看起来"首先执行了基础。
基类构造函数在派生类构造函数之前被调用,但是派生类构造函数在基类初始化构造函数之前被调用。例如。在以下代码中:
public class BaseClass { private string sentenceOne = null; // A public BaseClass() { sentenceOne = "The quick brown fox"; // B } } public class SubClass : BaseClass { private string sentenceTwo = null; // C public SubClass() { sentenceTwo = "jumps over the lazy dog"; // D } }
执行顺序为:C,A,B,D。
查看以下2条msdn文章:
- 为什么初始化程序与构造函数的运行顺序相反?第一部分
- 为什么初始化程序与构造函数的运行顺序相反?第二部分
首先将调用基本构造函数,否则,在"其他内容"必须使用由基本构造函数初始化的成员变量的情况下,我们将得到编译时错误,因为类成员尚未初始化。
在子构造函数中完成任何工作之前,将调用base(?)。
即使不使用:base()也是如此(在这种情况下,将调用0参数的基本构造函数。)
它的工作原理类似于Java,
public Child() { super(); // this line is always the first line in a child constructor even if you don't put it there! *** }
***例外:我可以改用super(1,2,3)。但是,如果我没有显式调用super,则会调用super()。
正如其他人所说,基本构造函数首先被调用。但是,构造函数并不是真正发生的第一件事。
假设我们有这样的课程:
class A {} class B : A {} class C : B {}
首先,将按从最高派生到最低派生的类的顺序调用字段初始化器。因此,首先是C的字段初始值设定项,然后是B的初始值设定项,然后是A的初始值。
然后将以相反的顺序调用这些构造函数:首先是A的构造函数,然后是B,然后是C。
构造函数调用从下往上调用(激发),并从上到下执行。因此,如果我们有从C类继承而来的C类,而B类又继承了A类,则在创建C类的实例时,将调用C的构造函数,从而依次调用B的讲师,而B的构造函数又将调用B的构造函数。 A.现在执行A的构造函数,然后执行B的构造函数,然后执行C的构造函数。
不要试图记住它,而是要向自己解释发生了什么。假设我们有一个名为Animal的基类和一个名为Dog的派生类。派生类为基类添加了一些功能。因此,在执行派生类的构造函数时,基类实例必须可用(以便可以向其添加新功能)。这就是为什么构造函数从基础执行到派生,而析构函数以相反的方式执行的原因,首先是派生的析构函数,然后是基础析构函数。
(这已简化,但是它可以将来无需实际记住此问题即可回答此问题。)
埃里克·利珀特(Eric Lippert)在对象初始化的相关问题上发表了一篇有趣的文章,其中解释了构造函数和字段初始化程序排序的原因:
为什么初始化程序以相反的顺序作为构造函数运行?第一部分
为什么初始化程序以相反的顺序作为构造函数运行?第二部分