using System; namespace Param { class Class1 { static int i = getNum(); int j = getNum(); static int num = 1; static int getNum() { return num; } [STAThread] static void Main(string[] args) { Console.WriteLine(string.Format("i={0}",i));
Console.WriteLine(string.Format("j={0}",new Class1().j));
Console.Read();
} } } 上面的代碼是一個(gè)網(wǎng)友告訴我的,讓我看看結(jié)果,我看了一眼馬上說(shuō)結(jié)果是 i=1 j=1 網(wǎng)友運(yùn)行后說(shuō)結(jié)果是 i=0 j=1 我嚇了一跳,認(rèn)真看了代碼,原來(lái)自己真的錯(cuò)了。 下面我解釋一下為什么是后一種結(jié)果 對(duì)一個(gè)類來(lái)說(shuō),static變量是與對(duì)象無(wú)關(guān)的,那么它們什么時(shí)候被初始化呢?就是在第一次引用的時(shí)候。當(dāng)類生成對(duì)象的時(shí)候,可以簡(jiǎn)單分成3步 1,為所有static變量分配內(nèi)存,這個(gè)時(shí)候內(nèi)存里面的值是該變量類型的缺省值。關(guān)于不同值類型的缺省值大家可以去查相關(guān)資料,注意值類型和引用類型是不同的。 2,為static變量賦值,同樣要注意值類型和引用類型是不同的。 3,生成對(duì)象,調(diào)用構(gòu)造函數(shù),先調(diào)用這個(gè)類的父類的構(gòu)造函數(shù),然后調(diào)用類本身的構(gòu)造函數(shù),生成對(duì)象。 現(xiàn)在分析上面的代碼: Console.WriteLine(string.Format("i={0}",i));這里i是static變量,而且類class1是第一次被引 用,按照上面說(shuō)的三步,要先為class1里面所有的static變量分配內(nèi)存。盡管現(xiàn)在有超線程技術(shù),但是指令在邏輯還是一條一條的按順序執(zhí)行的,所以 先為static int i分配內(nèi)存,并且在該內(nèi)存中保持int的缺省值0,接著再為static int num 變量分配內(nèi)存,值當(dāng)然也為0。 然后執(zhí)行第二步,為變量賦值:先為static int i變量賦值,i=getNum(),看getNum里面的代碼,就是return num,這個(gè)時(shí)候num的值是0,于是i就為0了。然后對(duì)變量num賦值,num=1;這行代碼執(zhí)行后,num就為1了。分析到這里我就不繼續(xù)分析了,大 家很容易看出結(jié)果是什么。 稍微熟悉c#的人,只要認(rèn)真看代碼,肯定不會(huì)出錯(cuò),但是如果拿來(lái)考人,相信很多人會(huì)做錯(cuò)。我認(rèn)為這個(gè)問(wèn)題簡(jiǎn)單得算不上一個(gè)技術(shù)問(wèn)題,所以放在非技術(shù)區(qū)。之 所以在上面說(shuō)那么多廢話來(lái)分析,是想說(shuō)明在編程的時(shí)候,即使非常熟悉、非常基本的東西,也要認(rèn)真。當(dāng)然如果我手下的人寫出這樣的代碼,肯定在代碼檢視的時(shí) 候被我痛批。事實(shí)上對(duì)static 值類型變量不直接賦值,而通過(guò)方法來(lái)賦值,是不常用或者是有點(diǎn)bt的做法,但是我仍然很佩服出題的人。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注