新聞中心
最近找工作,面試了幾家公司,其中有一家公司的面試題給我印象很深,不久前在博客園看過(guò)類似的題目,但這次的更復(fù)雜,題目如下:

員工經(jīng)過(guò)長(zhǎng)期磨合與沉淀,具備了協(xié)作精神,得以通過(guò)團(tuán)隊(duì)的力量開(kāi)發(fā)出優(yōu)質(zhì)的產(chǎn)品。創(chuàng)新互聯(lián)堅(jiān)持“專注、創(chuàng)新、易用”的產(chǎn)品理念,因?yàn)椤皩W⑺詫I(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡(jiǎn)單”。公司專注于為企業(yè)提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、電商網(wǎng)站開(kāi)發(fā),小程序設(shè)計(jì),軟件按需定制網(wǎng)站等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。
- public class BaseA
- {
- public static MyTest a1 = new MyTest("a1");
- public MyTest a2 = new MyTest("a2");
- static BaseA()
- {
- MyTest a3 = new MyTest("a3");
- }
- public BaseA()
- {
- MyTest a4 = new MyTest("a4");
- }
- public virtual void MyFun()
- {
- MyTest a5 = new MyTest("a5");
- }
- }
- public class BaseB : BaseA
- {
- public static MyTest b1 = new MyTest("b1");
- public MyTest b2 = new MyTest("b2");
- static BaseB()
- {
- MyTest b3 = new MyTest("b3");
- }
- public BaseB()
- {
- MyTest b4 = new MyTest("b4");
- }
- public new void MyFun()
- {
- MyTest b5 = new MyTest("b5");
- }
- }
- static class Program
- {
- static void Main()
- {
- BaseB baseb = new BaseB();
- baseb.MyFun();
- }
- }
- public class MyTest
- {
- public MyTest(string info)
- {
- Console.WriteLine(info);
- }
- }
最后的問(wèn)題是:請(qǐng)寫出Main()方法中,a1-a5,b1-b5這十個(gè)類實(shí)例化的順序。(MyTest類是我自己添的,方便查看結(jié)果,原題是是實(shí)例化一個(gè)object類。)
不知道園子里有多少人能胸有成竹的寫出正確答案,反正我是答錯(cuò)了,正確答案是:
b1
b3
b2
a1
a3
a2
a4
b4
b5
題目中涉及到的知識(shí)點(diǎn)
雖然題目沒(méi)做對(duì)了,但要知道自己為什么會(huì)做錯(cuò),這樣才會(huì)有所提高,趁著端午的假期,我把這個(gè)面試題涉及到的知識(shí)點(diǎn)都梳理了一遍,要點(diǎn)如下:
內(nèi)聯(lián)(inline)方式初始化字段。
類型構(gòu)造器(靜態(tài)構(gòu)造函數(shù))的執(zhí)行時(shí)間。
C#中基類和子類實(shí)例化的順序。
new修飾符的作用。
內(nèi)聯(lián)方式初始化字段
這個(gè)知識(shí)點(diǎn)在《CLR via C#》書中有講到,所謂內(nèi)聯(lián)方式,就是初始化字段的一種簡(jiǎn)化語(yǔ)法。來(lái)看示例代碼:
- public class SomeType
- {
- public int m_x = 5;
- }
這種在類中聲明變量時(shí)進(jìn)行賦值的方式就叫做內(nèi)聯(lián),大致等效于下面的代碼:
- public class SomeType
- {
- public int m_x;
- public SomeType()
- {
- m_x = 5;
- }
- }
之所以說(shuō)“大致等效”,因?yàn)閮烧叩膱?zhí)行順序上略有差異,編譯器會(huì)首先生成內(nèi)聯(lián)方式的代碼,然后再調(diào)用構(gòu)造函數(shù)。
比如,下面的代碼,最后m_x的結(jié)果就為10。
- public class SomeType
- {
- //先執(zhí)行
- public int m_x=5;
- public SomeType()
- {
- //后執(zhí)行
- m_x = 10;
- }
- }
類型構(gòu)造器的執(zhí)行
所謂類型構(gòu)造器也就是我們熟知的靜態(tài)構(gòu)造方法,在我們編寫的類中,都會(huì)有一個(gè)默認(rèn)的靜態(tài)無(wú)參構(gòu)造方法,跟無(wú)參實(shí)例構(gòu)造方法一樣是默認(rèn)存在的。
每當(dāng)我們對(duì)一個(gè)類創(chuàng)建第一個(gè)實(shí)例或訪問(wèn)靜態(tài)字段前,JIT編譯器就會(huì)調(diào)用該類的靜態(tài)構(gòu)造方法。當(dāng)然,靜態(tài)變量也可以使用上面說(shuō)的內(nèi)聯(lián)方法進(jìn)行賦值。
這里可以看出,當(dāng)?shù)谝淮螌?shí)例化某個(gè)類時(shí),會(huì)首先調(diào)用該類的靜態(tài)構(gòu)造方法。
C#中基類和子類實(shí)例化的順序
這個(gè)知識(shí)點(diǎn)比較簡(jiǎn)單,那就是在調(diào)用子類實(shí)例構(gòu)造方法之前會(huì)調(diào)用基類的實(shí)例構(gòu)造方法。從面試題的結(jié)果可以看出,基類的構(gòu)造方法又比子類的靜態(tài)構(gòu)造函數(shù)晚一些,此處因個(gè)人能力有限,我也沒(méi)辦法從更底層的角度去分析原理,只能暫且記住吧。
new修飾符的作用
我看過(guò)不少關(guān)于new以修飾符的形式用在方法聲明中的題目,關(guān)于new的用法在MSDN上也都查的到,官方說(shuō)法是“顯式隱藏從基類繼承的成員”。
我個(gè)人的理解比較簡(jiǎn)單:當(dāng)子類中,一個(gè)方法的簽名(指參數(shù),方法名,返回值)與基類的一個(gè)方法相同,通過(guò)加入new修飾符,可以讓子類不做更改的去使用該方法。
說(shuō)到底,new修飾符就是讓兩個(gè)不相關(guān)的同名方法同時(shí)存在而已。(這里同名指相同的方法簽名)
最后
回頭想想,其實(shí)在我日常的項(xiàng)目開(kāi)發(fā)中,多多少少都有涉及到這幾個(gè)問(wèn)題,只是平時(shí)不注意,沒(méi)有深究吃透,寫此文也是勉勵(lì)自己以后要重視基礎(chǔ),不再浮躁。
原文鏈接:http://www.cnblogs.com/hkncd/archive/2011/06/05/2073404.html
分享名稱:解析關(guān)于實(shí)例化順序的C#面試題
當(dāng)前鏈接:http://www.fisionsoft.com.cn/article/cdpjgpd.html


咨詢
建站咨詢
