筆試題 類中static變數

iDotNetSpace發表於2009-10-22
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();

  }  
  }  
  }  
  上面的程式碼是一個網友告訴我的,讓我看看結果,我看了一眼馬上說結果是  
  i=1  
  j=1  
  網友執行後說結果是  
  i=0  
  j=1  
  我嚇了一跳,認真看了程式碼,原來自己真的錯了。  
  下面我解釋一下為什麼是後一種結果  
  對一個類來說,static變數是與物件無關的,那麼它們什麼時候被初始化呢?就是在第一次引用的時候。當類生成物件的時候,可以簡單分成3步  
  1,為所有static變數分配記憶體,這個時候記憶體裡面的值是該變數型別的預設值。關於不同值型別的預設值大家可以去查相關資料,注意值型別和引用型別是不同的。  
  2,為static變數賦值,同樣要注意值型別和引用型別是不同的。  
  3,生成物件,呼叫建構函式,先呼叫這個類的父類的建構函式,然後呼叫類本身的建構函式,生成物件。  
  現在分析上面的程式碼:  
  Console.WriteLine(string.Format("i={0}",i));這裡i是static變數,而且類class1是第一次被引 用,按照上面說的三步,要先為class1裡面所有的static變數分配記憶體。儘管現在有超執行緒技術,但是指令在邏輯還是一條一條的按順序執行的,所以 先為static   int   i分配記憶體,並且在該記憶體中保持int的預設值0,接著再為static   int   num   變數分配記憶體,值當然也為0。  
  然後執行第二步,為變數賦值:先為static   int   i變數賦值,i=getNum(),看getNum裡面的程式碼,就是return   num,這個時候num的值是0,於是i就為0了。然後對變數num賦值,num=1;這行程式碼執行後,num就為1了。分析到這裡我就不繼續分析了,大 家很容易看出結果是什麼。  
   
  稍微熟悉c#的人,只要認真看程式碼,肯定不會出錯,但是如果拿來考人,相信很多人會做錯。我認為這個問題簡單得算不上一個技術問題,所以放在非技術區。之 所以在上面說那麼多廢話來分析,是想說明在程式設計的時候,即使非常熟悉、非常基本的東西,也要認真。當然如果我手下的人寫出這樣的程式碼,肯定在程式碼檢視的時 候被我痛批。事實上對static   值型別變數不直接賦值,而通過方法來賦值,是不常用或者是有點bt的做法,但是我仍然很佩服出題的人。 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-617194/,如需轉載,請註明出處,否則將追究法律責任。

相關文章