程序中聲明了一個Hashtable類型的對象:_eventList,每一個Class1類的實體都擁有這個對象,另外還聲明了兩個object類型的對象:_processStart、_processEnd,注意!這兩個對象是static(靜態)類型,也就是說,不管有多少個對象實體,都只須花費兩個object的空間。那這與2-4的范例做法有何不同呢?答案是對象所占的內存大小不同,當用戶創建一個對象實體之後,此對象占用了一個Hashtable對象的內存空間,在用戶設定了ProcessStart事件時,此對象隨之占用了一個Hashtable元素的內存空間,若用戶未設定事件,那麼此元素的內存空間就不會被占用,相較於2-4范例的預付行為,此方式可以省下不必要付出的內存成本。再詳細點說,假設Class1擁有1000個事件,那麼程序2-4的做法在對象創建初期就會占用1000個event變量的內存空間,而程序2-5則要付出一個Hashtable對象及1000個static變量的代價,當用戶創建了第二個對象時,程序2-4要再次占用了1000個event變量的代價,但程序5只須占用一個Hashtable對象的代價,優劣立見不是嗎?很幸運,這種設計概念在.Net Framework中已提供了基礎建設,設計人員只要套用即可,見程序6。
程序6 .Net Framework內建的事件支持
public class Component1:Component
{
private static object _processStart = new object();
public event EventHandler ProcessStart
{
add
{
Events.AddHandler(_processStart,value);
}
remove
{
Events.RemoveHandler(_processStart,value);
}
}
public void Process()
{
EventHandler handler = (EventHandler)Events[_processStart];
if(handler != null)
handler(this,null);
}
}
只要繼承自Component類或其子類就可使用這種方式來處理事件。
Static Helper Object
C#是個純OOP的語言,這代表著它不允許設計人員聲明全局性的函數或是變量,它提倡以靜態函數與靜態變量來取代原本須要使用全局性函數及變量的地方,由於靜態函數與靜態變量都要聲明於類內,這個限制形成群集的效應,同時引出了另一種類型的運用:Static Helper Object,見程序7。
程序7 Static Helper Object范例
public sealed class DomainHelper
{
public static string GetCurrentDomainDir()
{
return AppDomain.CurrentDomain.BaseDirectory;
}
private DomainHelper()
{}
}
............
MessageBox.Show(DomainHelper.GetCurrentDomainDir());
DomainHelper是一個不允許繼承且具備私有構造函數的類,這代表著設計人員不可能創建或是繼承此類,DomainHelper提供了GetCurrentDomainDir靜態函數,用來返回目前Application Domain所在的路徑,這比起原來調用AppDomain. GetCurrentDomain. BaseDirectory函數來取得同樣結果的方式簡短了許多。Helper Object的中心概念就是將常用的輔助型函數包裝成靜態函數,設計人員就無須一再重復地撰寫這些程序代碼,組件設計技術與Helper Object息息相關,讀者們會在後面的章節中看到更多這類型的例子。