在傳統上,我們宣告了一個Function(函式),若想要持續保留這個函式運行過程中的變數(例如一個累加器),那麼我們勢必要宣告一個全域變數(或是一個類別實體)來進行存放才可以。而到了泛型委派、通用委派(General Delegates)的世界裡面,寫法可以變得更精簡,以下是程式碼的示範:
static void Main(string[] args) { Func<int> oRun = Count(); oRun(); oRun(); oRun(); oRun(); int X = oRun(); //變數在過程中被保留,所以答案會是5 Console.WriteLine(X); } static Func<int> Count() { int i = 0; Func<int> oTemp = () => { i++; return i; }; return oTemp; }
在上述的程式碼中,Func<int>中的int其實代表的是<TResult>,並非傳入參數,因此這並不是一個類似遞迴的寫法,請不要誤會!
上面的例子中,是使用簡單的參數來進行運作,下面的例子就更進階了,我們透過建立Calc類別,並在中間建立可存取的參數以及簡單的累加方法。我們也可以在程式碼中看到,每一次的Func<Calc>呼叫,下面都會有一行new Calc()實體的建立,但事實上這一個實體只有在第一次建立,之後的委派調用,就回歸到全然的Func<Calc> oFunc此行運行了。
class Program { static void Main(string[] args) { Func<Calc> oRun = Count(); oRun(); oRun(); oRun(); oRun(); Calc X = oRun(); //輸出「計數器:5」 Console.WriteLine(String.Format("{0}:{1}", X.name, X.i)); } static Func<Calc> Count() { Calc oTemp = new Calc() { name = "計數器", i = 0 }; Func<Calc> oFunc = () => { oTemp.count(); return oTemp; }; return oFunc; } } class Calc { public string name { get; set; } public int i { get; set; } public void count() { i++; } }
現在的我還不知道這樣的寫法除了語法精簡之外還有什麼優勢,日後如果有遇到需要全域保留的實體類別或變數,或許我會慢慢考慮改採用這樣的寫法。
泛型委派 通用委派 GeneralDelegates 全域變數 GlobalVariable 區域變數 LocalVariable 保留 Reserved