10.C#匿名函數的變數捕獲(五章5.5)

來源:互聯網
上載者:User

標籤:

  首先感謝園友的指定,後續的文章一定會多碼多想,出來的文章才有說服力。那今天接上篇我們來聊一聊匿名函數,對於匿名函數,我們知道使用delegate關鍵字,那我們來需要知道匿名函數在變數是的處理方式,先說兩個術語,外部變數和捕獲的外部變數,可以看出"捕獲的外部變數=外部變數+捕獲了",這個捕獲顧名思義就是在匿名函數中使用了這個變數。

  外部變數:指在一個包含匿名方法的範圍內的變數或者參數,在類的執行個體成員內部的匿名方法,this也是認為是一個外部變數。

  捕獲的外部變數:它是指在匿名方法中使用的外部變數。

  代碼如下

 1 static void Main(string[] args) 2 { 3     //x和y稱為外部變數 4     int x = 0, y = 1; 5     //在匿名方法中使用到了x,則x稱為捕獲的外部變數 6     Action<int> ac = delegate (int n) { Console.WriteLine(x); }; 7  8     //小結:x、y和匿名方法都在Main函數的範圍內,也可以擴充到類的範圍及命名空間的範圍 9 10     Console.ReadKey();11 }

  再來說下匿名方法捕獲變數的行為,可以看到在匿名方法中我們訪問到了局部變數x,請注意,並不是僅僅訪問到了x的值,而是在匿名型別中使用一個類型執行個體引用到了變數x,對於x的改變,因為是引用,所以總能使用這個類型執行個體訪問到,如

1 long x1 = 11, y1 = 12;2 Action<long> ac1 = delegate (long l) { Console.WriteLine(x1); };3 ac1(1L); //列印114 x1 = y1;5 ac1(1L);  //列印12

  參數long l這裡沒有使用到,不過這裡的參數不是上面所說的外部變數,因為它確實是匿名方法的參數

1 static void Debug(int x) {2     Action<int> a = delegate (int y) { Console.WriteLine(x); };3 }

  上面的x就是術語中說的外部變數,分清定義就應該沒問題了吧。

  關於變數的生存周期,可以就只在一個範圍內,當代碼執行完這個範圍,該範圍內的變數也會被銷毀,但使用匿名方法可以延長變數的生存周期。

 1 static void Main(string[] args) 2 { 3     GetLen gl = GetMethod(); 4     gl("s"); //列印00s 5     gl("s"); //列印0000s 6  7     Console.ReadKey(); 8 } 9 10 public delegate int GetLen(string s);11 static GetLen GetMethod()12 {13     string temp = "0";14     return delegate (string s) {15         temp = String.Concat(temp, temp);16         s = String.Concat(temp, s);17         Console.WriteLine(s);18         return s.Length;19     };20 }

  看出使用GetMethod返回一個委託,這裡使用匿名函數(因為匿名函數就是對應簽名的委託),在正常理解下temp在GetMethod範圍內,當離開範圍外,這個變數會銷毀,但說過匿名函數會使用一個類型執行個體引用這個變數,則這個變數不會銷毀,只有當匿名函數銷毀(也就是委託)才會跟著銷毀,從而延長了變數的範圍,而且對於temp變數的操作也會直接反應在執行個體引用的變數上,如第一次調用gl("s"),temp="00",第二次調用時,temp="0000"。

   最後說下有點繞的東西,就是變數的執行個體化在匿名函數中的訪問規則,不過個人感覺這個還真是不很繞,還算是比較好理解的。看下代碼。

 1 GetLen[] a = { }; 2 int xx = 0; 3 for (int i = 0; i < 3; i++) 4 { 5     int xxx = i; 6     a[i] = delegate (string s) { 7         xx++; 8         xxx++; 9         return xx + xxx;10     };11 }

  a是一個委託數組,對於數組中每一個委託都共用一個xx執行個體引用,而每一個委託都各自擁有一個xxx執行個體引用(xxx對應不同的委託是不同的),這是因為在迴圈中,每一次的迴圈都執行個體化了xxx,則對於各個委託都有一個全新的xxx執行個體引用,而xx則是在迴圈之外執行個體化的,則每個委託共用一個執行個體引用。當然在實際的使用過程中,不可能那麼簡單,那麼要我們開動大腦,好好區別哪一個共用的,哪一個是獨自引用的。

  請斧正。

 

10.C#匿名函數的變數捕獲(五章5.5)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.