構(gòu)造函數(shù)這玩意也是面試官經(jīng)常會(huì)問(wèn)到的東西,我們知道一個(gè)類(lèi)的狀態(tài)初始化就全靠它了,下面提幾個(gè)小問(wèn)題。
Q:我看到Web項(xiàng)目里面通常都有一個(gè)BasePage頁(yè)面,其中構(gòu)造函數(shù)里面做了權(quán)限驗(yàn)證,
請(qǐng)問(wèn)為什么要這么做。
A: 既然這么做了,那么設(shè)計(jì)者肯定就知道了一個(gè)原則就是實(shí)例構(gòu)造器中,父類(lèi)構(gòu)造器先于子類(lèi)執(zhí)行,那么這個(gè)先執(zhí)行就可
以做很多有意思的事情,比如你說(shuō)的權(quán)限驗(yàn)證,可能有人會(huì)問(wèn)為什么要先于子類(lèi)執(zhí)行,剛才我也說(shuō)了,構(gòu)造函數(shù)是用于
初始化本類(lèi)狀態(tài)的,這也叫“先掃屋子再請(qǐng)客”的道理吧~,然后風(fēng)雨兼程的回溯到Object的ctor中。好了,現(xiàn)在來(lái)回答
你的問(wèn)題,先把這個(gè)問(wèn)題簡(jiǎn)化一下,就不用web項(xiàng)目來(lái)演示了。
1 public class PRogram 2 { 3 static void Main(string[] args) 4 { 5 var b = new Bird(); 6 7 Console.Read(); 8 } 9 }10 11 public class Animal12 {13 public Animal()14 {15 Console.WriteLine("running first... i'm animal, all must be running after me.");16 }17 }18 19 public class Bird : Animal20 {21 public Bird()22 {23 Console.WriteLine("the next... i'm a cute bird.");24 }25 }

可以看到,確實(shí)Animal于Bird先執(zhí)行,可能有人會(huì)問(wèn),那Animal調(diào)用的是誰(shuí)的ctor呢?當(dāng)然就是Object了,我們可以看看IL:

Q: 既然你說(shuō)構(gòu)造函數(shù)用于初始化類(lèi)的初始狀態(tài),那么請(qǐng)問(wèn)下,我現(xiàn)在有一串這樣的
json:{"Name":"smart","Age":2}。實(shí)體類(lèi)如下圖,請(qǐng)問(wèn)我的json序列化后,Age=?
1 [Serializable] 2 public class Bird 3 { 4 private string name = "smart"; 5 6 public string Name 7 { 8 get { return name; } 9 set { name = value; }10 }11 12 private int age = 2;13 14 public int Age15 {16 get { return age; }17 set { age = value; }18 }19 20 public Bird()21 {22 Age = 5;23 }24 }
A:其實(shí)這個(gè)問(wèn)題的關(guān)鍵在于,反序列化的時(shí)候是否會(huì)調(diào)用構(gòu)造函數(shù)的問(wèn)題,先來(lái)通過(guò)Reflector看下源碼,發(fā)現(xiàn)并沒(méi)有代碼,覺(jué)得
有點(diǎn)小奇怪,就用ILSpy反編譯一下,同樣也沒(méi)有代碼,不可否認(rèn),底層肯定是有代碼執(zhí)行的,要么反編譯不出來(lái),要么clr用了
其他的方式,反正我們看不到實(shí)現(xiàn)源代碼,如果大家有什么好意見(jiàn)可以幫幫我,謝謝了
Reflector截圖:

ILSpy截圖:

據(jù)資料說(shuō),里面最后調(diào)用了FormatterServices里面的GetSafeUninitializedObject來(lái)分配對(duì)象內(nèi)存,分配完后就不走構(gòu)造器
了,所以針對(duì)這個(gè)問(wèn)題,只能記住了。最后為了驗(yàn)證一下,執(zhí)行完代碼之后確實(shí)沒(méi)有走構(gòu)造函數(shù)。

Q:我知道引用類(lèi)型可以用構(gòu)造器,那值類(lèi)型為什么不能定義無(wú)參構(gòu)造器?

A:這個(gè)問(wèn)題問(wèn)的好,編譯器會(huì)根據(jù)性能考慮,不會(huì)調(diào)用值類(lèi)型的構(gòu)造函數(shù),即使你強(qiáng)制的new一下也不會(huì)執(zhí)行
1 namespace Sample 2 { 3 public class Program 4 { 5 static void Main(string[] args) 6 { 7 Point point = new Point(); 8 } 9 }10 11 public struct Point12 {13 public int Age;14 }15 }

不過(guò)除非你自己顯示定義有參構(gòu)造函數(shù),而且值類(lèi)型有個(gè)特點(diǎn)就是讀取之前必須初始化,否則會(huì)編譯不通過(guò)。

Q:請(qǐng)問(wèn)在類(lèi)構(gòu)造函數(shù)中能做單例嗎?
A: 能不能做,就要看類(lèi)構(gòu)造器的特征了,我們知道類(lèi)構(gòu)造器跟實(shí)例構(gòu)造器一樣,他是用來(lái)初始化靜態(tài)字段的,線(xiàn)程
訪(fǎng)問(wèn)類(lèi)構(gòu)造器的時(shí)候內(nèi)部會(huì)進(jìn)行加鎖處理,所以多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)的時(shí)候,只會(huì)有一個(gè)線(xiàn)程執(zhí)行了類(lèi)構(gòu)造器,所以
確實(shí)可以。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注