泛型委派(General Delegates)之變數保留寫法

在傳統上,我們宣告了一個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其實代表的是<TResult>,並非傳入參數,因此這並不是一個類似遞迴的寫法,請不要誤會!

類別型態的參數保留寫法

上面的例子中,是使用簡單的參數來進行運作,下面的例子就更進階了,我們透過建立Calc類別,並在中間建立可存取的參數以及簡單的累加方法。我們也可以在程式碼中看到,每一次的Func呼叫,下面都會有一行new Calc()實體的建立,但事實上這一個實體只有在第一次建立,之後的委派調用,就回歸到全然的Func 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