簡單的說,Lambda-Expression是一種匿名函式的描述方式,我的習慣裡,通常配合Delegate一起服用(即時性的產生函式物件) 寫法長成這樣:
static Func另外一個有趣的事情是,在CLR的記憶體模型中,delegateInstance = new Func (() => { Console.WriteLine("I was prisoned in Lambda!!!"); return 0; });
ByReference物件生命週期並不是離開函式Scope就消失,
而是不再有人參考到此物件時,這飄渺在記憶體太空的虛無之物才會被GC回收,
所以可能會出現,在Lambda生成時,Lambda去參考函式局部範圍下的某個Object, 即便離開生成函式,一直到Lambda執行時,
這個Object仍然被保持住,而Lambda得以順利執行。
會有種 物件小姐 從 生成他的函式酒店 被"帶出場"的感覺(威~):
static int createLambda() { String theInstance = "I was created in createLambda()"; delegateInstance = new Func最後分享一個案例,若在Foreach中想要替陣列裡的每個物件創造對應的Lambda,在Lambda執行時,能反應陣列裡各物件的狀態(一個Lambda反應一個物件) 此時放在Lambda內的應該要用哪個具名參考?(() => { Console.WriteLine(theInstance.ToString()); return 0; }); return 0; } static int executeLambda() { delegateInstance(); return 0; } static void Main(string[] args) { createLambda(); executeLambda(); //' theInstance still kept, so that no NullReferenceException would raise }
- Iterator?
- 在Foreach外宣告一個參考?
- 在Foreach內宣告參考?
static void Main(string[] args) { ListtheList = new List (); Random rnd = new Random(); Console.WriteLine("Peek answers"); for (int i = 0; i < 10; i++) { myClass instance = new myClass(); instance.myString = rnd.Next().ToString(); theList.Add(instance); Console.WriteLine(instance.ToString()); } Console.WriteLine("Peek over"); delegateInstance = null; //myClass tempReference ; // option 2 foreach (myClass item in theList) { //myClass tempReference = item; // option 3 //tempReference = item; delegateInstance += new Func (() => { //Console.WriteLine(tempReference.ToString()); Console.WriteLine(item.ToString()); // option 1 return 0; }); } Console.WriteLine("Lambda run"); delegateInstance(); // the invocation list Console.WriteLine("Lambda finish"); }
答案是1、3都可(兩者效果等價),Foreach下的Reference在Iterator進到下一格時,會全部Refresh 所以各個Lambda內參考到的物件彼此是不相同的(連結到不同指標),即便程式碼中他們都是同名的變數。
相反地,選項2用的Reference在Foreach外宣告,相當於只用一個指標去連結不同的物件 但Lambda們都是以同一個指標去參考物件,所以印出來的東西都是一樣的。