12.18.2006

.NET 漫談 (1)

.NET的程式開發過程裡,New這個動作到底代表了甚麼,我想這個要從Object life cycle(物件的生命週期)講起。

在電腦的世界裡面,我們定義的Class代表的就是一個我們設定好的記憶體模型,可以把它當作一個模子,我們可能準備了許多的模子,但是不代表我們有用模子壓出東西來,這個時候算是準備時期,程式開發的術語叫做Design-Time

當程式開始執行之後,這時候的狀態叫做Run-Time。這個時候電腦會根據你想要的東西,找到相對應的模子在記憶體裡面壓出你所想要的東西,這個東西叫做Object,你也可以稱它為Instance,不管Object或是Instance都是佔有記憶體的。

好啦,假設我們有兩個模子,要壓出小白兔跟花,所以一個叫做Rabbit,另一個叫做Flower,那我們要怎麼叫電腦幫我們做產生Object的動作呢?我們需要寫下像下面的的程式碼:

Rabbit melody=new Rabbit();
Flower rose=new Flower();

沒錯,New就是建立Instance的動作。但是你的內心一定有一些疑惑,那為甚麼有些東西需要New,但是有些東西不用New。

這個問題就回到我們以前討論的Value Type與Reference Type的差異。這兩個形態的分別就是因為Value Type夠簡單,夠單純,.NET可以完全掌控它,所以一般來說它是不需要New的,但是你可以試試看下面的程式碼:

Int32 i = new Int32();

然後Build看看,IDE應該只會吐一個warning CS0219: The variable 'i' is assigned but its value is never used警告訊息給你,還是可以過的。

所以說Value Type也是可以New的,只是.NET本身認為他很單純,簡單,所以Value Type才可以略過。再進一步的說來,.NET將(Type)區分成兩種大類,一種是所謂的Primitive Type, 也就是我們剛剛講的Value Type,不管是Primitive Type還是Reference Type的Instance都是在Runtime配置在記憶體中,但是兩者之間配置的位置是不一樣的,Reference Type是位在Heap裡面,受GC的管理,但Primitive Type是不在GC Heap裡面。

所以相對的Primitive Type的Instance在使用上會比較沒有額外的負擔,但是要記住,Primitive Type是記憶體大小不可變的,也就是當你宣告變數是Int32的型別之後,並無法改變它的大小,這部分我們就要注意System.String這個型別,這個型別的特殊的地方是它是個Reference Type,但它的狀態也是記憶體大小不可變,這個有看過String與StringBuilder比較的Demo都應該可以快速的體認到差異並懂得避免非效率的Coding行為。