當你第一次申請黑色畫刷時,Brushes類就會創建它。然而 Brushes類就保留一個單一的黑色畫刷的引用句柄,當你再次申請時它就直接返 回這個句柄。結果就是你只創建了一個黑色畫刷並且一直在重用它。另外,如果 你的應用程序不須要一個特殊的資源,一個檸檬綠(lime green)的畫刷就可能永 遠不會創建。框架提供了一個方法來限制對象,使得在滿足目標的情況下使用最 小的對象集合。學會在你的應用程序裡使用這樣的技巧。
你已經學會了 兩種技術來最小化應用程序的(對象)分配數量,正如它承擔它自己的任務一樣。 你可以把一個經常使用的局部變量提升為類的成員變量,你可以提供一個類以單 件模式來存儲一些常用的給定對象的實例。最後一項技術還包括創建恆定類型的 最終使用值。System.String類就是一個恆定類型,在你創建一個字符串後,它 的內容就不能更改了。當你編寫代碼來修改這些串的內容時,你實際上是創建了 新的對象,並且讓舊的串成為了垃圾。這看上去是清白的例子:
string msg = "Hello, ";
msg += thisUser.Name;
msg += ". Today is ";
msg += System.DateTime.Now.ToString();
這實際上低效的如果你是這 樣寫:
string msg = "Hello, ";
// Not legal, for illustration only:
string tmp1 = new String( msg + thisUser.Name );
string msg = tmp1; // "Hello " is garbage.
string tmp2 = new String( msg + ". Today is " );
msg = tmp2; // "Hello <user>" is garbage.
string tmp3 = new String( msg + DateTime.Now.ToString( ) );
msg = tmp3;// "Hello <user>. Today is " is garbage.
字符串tmp1,tmp2,tmp3以及最原始的msg構造的 (“Hello”),都成了垃圾。+=方法在字符串類上會生成一個新的對 象並返回它。它不會通過把字符鏈接到原來的存儲空間上來修改結果。對於先前 這個例子,給一個簡單的構造例子,你應該使用string.Format()方法:
string msg = string.Format ( "Hello, {0}. Today is {1}",
thisUser.Name, DateTime.Now.ToString( ));
對於更多的復雜的字符串操作,你應該使用StringBuilter類 :
StringBuilder msg = new StringBuilder( "Hello, " );
msg.Append( thisUser.Name );
msg.Append( ". Today is " );
msg.Append( DateTime.Now.ToString());
string finalMsg = msg.ToString();
StringBuilder也一個( 內容)可變的字符串類,用於生成恆定的字符串對象。在你還沒有創建一個恆定 的字符串對象前,它提供了一個有效的方法來存儲可變的字符串。更重要的是, 學習這樣的設計習慣。當你的設計提倡使用恆定類型時(參見原則7),對於一些 要經過多次構造後才能最終得到的對象,可以考慮使用一些對象生成器來簡化對 象的創建。它提供了一個方法讓你的用戶來逐步的創建(你設計的)恆定類型,也 用於維護這個類型。
(譯注:請理解作者的意圖,只有當你使用恆定類型 時才這樣,如果是引用類型,就不一定非要使用對象生成器了。而且注意恆定類 型的特點,就是一但創建就永遠不能改變,所有的修改都會產生新的實例, string就是一個典型的例子,它是一個恆定的引用類型;還有DateTime也是一個 ,它是一個恆定的值類型。)
垃圾回收器在管理應用程序的內存上確實很 高效。但請記住,創建和釋放堆對象還是很占時間的。避免創建大量的對象,也 不要創建你不使用的對象。也要避免在局部函數上多次創建引用對象。相反,把 局部變量提供為類型成員變量,或者把你最常用的對象實例創建為靜態對象。最 後,考慮使用可變對象創建器來構造恆定對象。
返回教程目錄