精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C# 本地函數與 Lambda 表達式

開發 后端
C# 局部函數通常被視為 lambda 表達式的進一步增強。雖然功能是相關的,但也存在重大差異。

[[420552]]

本文轉載自微信公眾號「DotNET技術圈」,作者Vladimir Sadov。轉載本文請聯系DotNET技術圈公眾號。

C# 局部函數通常被視為 lambda 表達式的進一步增強。雖然功能是相關的,但也存在重大差異。

Local Functions 是嵌套函數[1]功能的 C# 實現。一種語言在支持 lambdas 之后獲得對嵌套函數的支持幾個版本是有點不尋常的。通常情況相反。

Lambda 或一般的一流函數需要實現未在堆棧上分配且生命周期與需要它們的功能對象相關聯的局部變量。如果不依賴垃圾收集或通過捕獲列表等解決方案將變量所有權的負擔減輕給用戶,則幾乎不可能正確有效地實現它們。對于某些早期語言來說,這是一個嚴重的阻塞問題。嵌套函數的簡單實現不會遇到這種復雜情況,因此一種語言更常見的是僅支持嵌套函數而不支持 lambda。

無論如何,由于 C# 長期以來一直使用 lambda,因此從差異和相似之處來看本地函數確實是有意義的。

Lambda 表達式

Lambda 表達式x => x + x是抽象地表示一段代碼以及它如何綁定到其詞法環境中的參數和變量的表達式。作為代碼的抽象表示,lambda 表達式不能單獨使用。為了使用由 lambda 表達式生成的值,需要將其轉換為更多內容,例如委托或表達式樹。

  1. using System; 
  2. using System.Linq.Expressions; 
  3.  
  4. class Program 
  5.     static void Main(string[] args) 
  6.     { 
  7.         // can't do much with the lambda expression directly 
  8.         // (x => x + x).ToString();  // error 
  9.  
  10.         // can assign to a variable of delegate type and invoke 
  11.         Func<intint> f = (x => x + x); 
  12.         System.Console.WriteLine(f(21)); // prints "42" 
  13.  
  14.         // can assign to a variable of expression type and introspect 
  15.         Expression<Func<intint>> e = (x => x + x); 
  16.         System.Console.WriteLine(e);     // prints "x => (x + x)" 
  17.     } 

有幾點值得注意:

  • lambdas 是產生函數值的表達式。
  • lambda 值的生命周期是無限的——從 lambda 表達式的執行開始,只要存在對該值的任何引用。這意味著 lambda 從封閉方法中使用或“捕獲”的任何局部變量都必須在堆上分配。由于 lambda 值的生命周期不受產生它的堆棧幀的生命周期的限制,因此不能在該堆棧幀上分配變量。
  • lambda 表達式要求在執行 lambda 表達式時明確分配主體中使用的所有外部變量。lambda 的第一次和最后一次使用的時刻很少是確定性的,因此該語言假設 lambda 值可以在創建后立即使用,只要它們是可訪問的。因此,一個 lambda 值在創建時必須是完全可用的,并且它使用的所有外部變量都必須明確分配。
  1. int x; 
  2.  
  3.      // ERROR: 'x' is not definitely assigned 
  4.      Func<int> f = () => x; 
  • lambdas 沒有名字,也不能被象征性地引用。特別是 lambda 表達式不能遞歸聲明。

注意:可以通過調用分配給 lambda 的變量或傳遞給自應用其參數的高階方法來創建遞歸 lambda(請參閱:C# 中的匿名遞歸[2]),但這不會表達真正的自我參照。

本地函數

局部函數基本上只是在另一個方法中聲明的方法,作為一種降低方法對其聲明范圍內的可見性的方法。

自然地,局部函數中的代碼可以訪問其包含范圍內可訪問的所有內容——局部變量、封閉方法的參數、類型參數、局部函數。一個值得注意的例外是外部方法標簽的可見性。封閉方法的標簽在局部函數中不可見。這只是普通的詞法范圍,它的工作原理與 lambdas 相同。

  1. public class C 
  2.     object o; 
  3.  
  4.     public void M1(int p) 
  5.     { 
  6.         int l = 123; 
  7.  
  8.         // lambda has access to o, p, l, 
  9.         Action a = ()=> o = (p + l); 
  10.     } 
  11.  
  12.     public void M2(int p) 
  13.     { 
  14.         int l = 123; 
  15.  
  16.         // Local Function has access to o, p, l, 
  17.         void a() 
  18.         { 
  19.           o = (p + l); 
  20.         } 
  21.     } 

與 lambda 的明顯區別在于局部函數具有名稱并且可以在沒有任何間接方式的情況下使用。局部函數可以是遞歸的。

  1. static int Fac(int arg) 
  2.     int FacRecursive(int a) 
  3.     { 
  4.         return a <= 1 ? 
  5.                     1 : 
  6.                     a * FacRecursive(a - 1); 
  7.     } 
  8.  
  9.     return FacRecursive(arg); 

與 lambda 表達式的主要語義區別在于局部函數不是表達式,它們是聲明語句。在代碼執行方面,聲明是非常被動的實體。事實上,聲明并沒有真正被“執行”。與標簽等其他聲明類似,局部函數聲明只是將函數引入包含范圍,而無需運行任何代碼。

更重要的是,無論是聲明本身還是嵌套函數的常規調用都不會導致對環境的不確定捕獲。在簡單和常見的情況下,如普通的調用/返回場景,捕獲的局部變量不需要進行堆分配。

例子:

  1. public class C 
  2. {     
  3.     public void M() 
  4.     { 
  5.         int num = 123; 
  6.  
  7.         // has access to num 
  8.         void  Nested() 
  9.         { 
  10.            num++; 
  11.         } 
  12.  
  13.         Nested(); 
  14.  
  15.         System.Console.WriteLine(num); 
  16.     } 

上面的代碼大致相當于(反編譯):

  1. public class C 
  2.   // A struct to hold "num" variable. 
  3.   // We are not storing it on the heap, 
  4.   // so it does not need to be a class 
  5.   private struct <>c__DisplayClass0_0 
  6.   { 
  7.       public int num; 
  8.   } 
  9.  
  10.   public void M() 
  11.   { 
  12.       // reserve storage for "num" in a display struct on the _stack_ 
  13.       C.<>c__DisplayClass0_0 env = default(C.<>c__DisplayClass0_0); 
  14.  
  15.       // num = 123 
  16.       env.num = 123; 
  17.  
  18.       // Nested() 
  19.       // note - passes env as an extra parameter 
  20.       C.<M>g__a0_0(ref env); 
  21.  
  22.       // System.Console.WriteLine(num) 
  23.       Console.WriteLine(env.num); 
  24.   } 
  25.  
  26.     // implementation of the the "Nested()"
  27.     // note - takes env as an extra parameter 
  28.     // env is passed by reference so it's instance is shared 
  29.     // with the caller "M()" 
  30.     internal static void <M>g__a0_0(ref C.<>c__DisplayClass0_0 env) 
  31.     { 
  32.         env.num += 1; 
  33.     } 

請注意,上面的代碼直接調用了“Nested()”的實現(不是通過委托間接),并且沒有在堆上引入顯示存儲的分配(就像 lambda 會那樣)。局部變量存儲在結構中而不是類中。的生命周期num并沒有因為它在 中的使用而改變Nested(),所以它仍然可以在棧上分配。M()可以只通過num引用傳遞,但編譯器使用結構體進行打包,因此它可以傳遞所有本地變量,就像num只使用一個 env 參數一樣。

另一個有趣的一點是,只要本地函數在給定范圍內可見,就可以使用它們。這是一個重要的事實,使遞歸和相互遞歸的場景成為可能。這也使得本地函數聲明在源代碼中的確切位置在很大程度上變得不重要。

例如,封閉方法的所有變量必須在調用讀取它們的本地函數時明確分配,而不是在其聲明時。實際上,如果調用可以更早發生,那么在聲明時提出該要求將沒有任何好處。

  1. public void M() 
  2.     // error here - 
  3.     // Use of unassigned local variable 'num' 
  4.     Nested(); 
  5.  
  6.     int num; 
  7.  
  8.     // whether 'num' is assigned here or not is irrelevant 
  9.     void  Nested() 
  10.     { 
  11.        num++; 
  12.     } 
  13.  
  14.     num = 123; 
  15.  
  16.     // no error here - 'num' is assigned 
  17.     Nested(); 
  18.  
  19.     System.Console.WriteLine(num); 

此外 - 如果從未使用過局部函數,它也不會比一段無法訪問的代碼和任何變量更好,否則它會使用,不需要分配。

  1. public void M() 
  2. {         
  3.     int num; 
  4.  
  5.     // warning - Nested() is never used. 
  6.     void  Nested() 
  7.     { 
  8.        // no errors on unassigned 'num'
  9.        // this code never runs. 
  10.        num++; 
  11.     } 

那么,局部函數的目的是什么?

與 lambdas 相比,局部函數的主要價值主張是局部函數在概念上和運行時開銷方面都更簡單。

Lambda 可以很好地充當一類函數[3]的角色,但有時您只需要一個簡單的助手。分配給局部變量的 Lambda 可以完成這項工作,但存在間接開銷、委托分配和可能的閉包開銷。私有方法也有效,調用成本更低,但存在封裝問題,或缺乏封裝。這樣的助手對包含類型中的每個人都是可見的。太多這樣的幫手會導致嚴重的混亂。

局部函數非常適合這種情況。調用本地函數的開銷與調用私有方法的開銷相當,但使用其他不應調用的方法污染包含類型沒有問題。

http://mustoverride.com/local_functions/

References

[1] 嵌套函數: https://en.wikipedia.org/wiki/Nested_function

[2] C# 中的匿名遞歸: https://blogs.msdn.microsoft.com/wesdyer/2007/02/02/anonymous-recursion-in-c/ 

[3] 一類函數: https://en.wikipedia.org/wiki/First-class_function

 

責任編輯:武曉燕 來源: DotNET技術圈
相關推薦

2009-08-27 09:44:59

C# Lambda表達

2024-03-25 13:46:12

C#Lambda編程

2009-08-27 09:57:50

C# Lambda表達

2009-08-26 16:17:23

C# Lambda表達

2009-07-09 09:51:07

Lambda表達式C#

2020-10-16 06:40:25

C++匿名函數

2009-09-14 13:57:20

C# Lambda表達Lambda表達式

2010-09-14 14:05:42

C#委托

2011-05-20 17:50:45

C#

2010-10-19 10:03:02

Lambda表達式

2022-11-07 07:11:19

C#lambda函數

2009-08-31 17:11:37

Lambda表達式

2009-08-07 15:41:39

C#正規表達式

2009-07-01 09:56:10

C#3.0

2023-11-02 08:25:58

C++Lambda

2009-09-11 09:48:27

Linq Lambda

2022-12-05 09:31:51

接口lambda表達式

2009-09-15 15:18:00

Linq Lambda

2009-09-09 13:01:33

LINQ Lambda

2009-08-03 17:27:14

C#正則表達式
點贊
收藏

51CTO技術棧公眾號

亚洲免费在线电影| 亚洲午夜激情在线| 宅男在线国产精品| 精品视频在线观看一区二区| 亚洲第一页综合| 精品国产福利在线| 性日韩欧美在线视频| 偷拍女澡堂一区二区三区| 久久久久久一区二区三区四区别墅| 国产精品刘玥久久一区| 国产不卡视频在线播放| 欧美综合第一页| 三级黄色片在线观看| 成人h动漫免费观看网站| 色综合久久久久久久| 国产免费xxx| 视频在线观看你懂的| 欧美aaaaa成人免费观看视频| 久久精品视频中文字幕| 99re久久精品国产| 亚洲伦理一区二区| 色美美综合视频| 黄色特一级视频| 国产在线观看免费| 成人免费视频caoporn| 国产三级精品网站| www.日韩一区| 国产精品亚洲产品| 欧美裸体xxxx极品少妇| 欧美熟妇激情一区二区三区| 91蝌蚪精品视频| 欧美另类变人与禽xxxxx| 白嫩少妇丰满一区二区| 日本色护士高潮视频在线观看| 日本一区二区成人在线| 六月婷婷久久| 天堂网在线观看视频| 国产成人精品免费在线| 成人欧美一区二区三区在线| 天天干天天插天天射| 亚洲欧美成人综合| 26uuu亚洲伊人春色| 国产五月天婷婷| 欧美久色视频| 久久久av亚洲男天堂| 刘亦菲国产毛片bd| 色乱码一区二区三区网站| 亚洲欧美综合区自拍另类| 伊人网综合视频| caoporn成人免费视频在线| 51久久夜色精品国产麻豆| 一区二区三区入口| 99re久久| 欧美日本一区二区在线观看| 中文字幕在线观看第三页| 欧美××××黑人××性爽| 色婷婷综合在线| 青青青国产在线视频| 美女一区网站| 在线欧美一区二区| 一区二区三区入口| va天堂va亚洲va影视| 91麻豆精品国产自产在线观看一区| 热久久久久久久久| www.久久99| 精品国偷自产国产一区| youjizz.com日本| 精品伊人久久久| 精品亚洲国产视频| 中字幕一区二区三区乱码| 精品成人影院| 久久人人爽亚洲精品天堂| 中文字幕电影av| 影音先锋一区| 欧美一性一乱一交一视频| av片免费观看| 久久99这里只有精品| 91精品视频专区| 人妻妺妺窝人体色www聚色窝| 成人高清伦理免费影院在线观看| 久热国产精品视频一区二区三区| 国产三级视频在线播放线观看| 中文字幕成人在线观看| 国产人妻人伦精品| 九九色在线视频| 狠狠久久亚洲欧美专区| 亚洲色图 在线视频| 麻豆国产一区| 国产婷婷97碰碰久久人人蜜臀| 超碰人人干人人| 最新国产精品| 欧美亚洲视频一区二区| 一区二区视频免费| 成人午夜av影视| 欧美性xxxx69| 性欧美videoshd高清| 精品国产电影一区| 91性高潮久久久久久久| 天堂99x99es久久精品免费| 中文字幕精品久久久久| 国产这里有精品| 久久深夜福利| 国产精品国产精品国产专区蜜臀ah | 色爱综合av| 精品国模在线视频| 成人精品免费在线观看| 紧缚奴在线一区二区三区| 精品91免费| 国产黄色小视频在线| 欧美日韩在线第一页| 亚洲自拍第三页| 国产一区二区区别| 久久久免费精品| 国产精品呻吟久久| 91色在线porny| 人妻激情另类乱人伦人妻| 8av国产精品爽爽ⅴa在线观看| 精品粉嫩超白一线天av| 婷婷国产成人精品视频| 久久高清一区| 精品视频导航| 先锋成人av| 欧美精品亚洲二区| 人妻熟人中文字幕一区二区| 一本色道久久综合亚洲精品不卡| 92看片淫黄大片欧美看国产片| 成人精品一区二区三区校园激情| 午夜婷婷国产麻豆精品| 国产又粗又猛大又黄又爽| 成人在线免费观看视频| 欧美重口另类videos人妖| 亚洲精品国产av| 一区二区三区视频在线看| 久久久久久久高清| 四季av一区二区凹凸精品| 国产成人拍精品视频午夜网站| 日韩精品福利| 欧美日韩另类字幕中文| 精品影片一区二区入口| 狠狠爱成人网| 高清不卡日本v二区在线| 182tv在线播放| 91精品免费在线| √天堂中文官网8在线| 捆绑变态av一区二区三区| 日韩欧美精品在线不卡| 丝袜美腿一区| 亚洲欧洲在线免费| 欧美日韩a v| 久久精品视频网| 成人免费毛片播放| 成人情趣视频网站| 国产裸体写真av一区二区| av色图一区| 在线电影一区二区三区| 日韩一区二区不卡视频| 国产一区二区三区在线看麻豆| 性生活免费观看视频| av成人综合| 91tv亚洲精品香蕉国产一区7ujn| 深夜视频在线免费| 色噜噜狠狠成人网p站| 日本爱爱爱视频| 久久成人免费日本黄色| 黄色网zhan| 一区二区三区在线免费看| 韩剧1988在线观看免费完整版| 天天射天天色天天干| 日本道色综合久久| 黑人狂躁日本娇小| 国产高清久久久| 欧美精品久久久久久久自慰| 蜜臀av免费一区二区三区| 国产精品xxx视频| 巨大荫蒂视频欧美大片| 精品久久久久久久久久久久包黑料 | 99国内精品| 日韩av影视| 国产成人免费视频网站视频社区| 久久久久久成人精品| 亚洲三区在线观看无套内射| 欧美吻胸吃奶大尺度电影| 午夜精品福利在线视频| av在线这里只有精品| 十八禁视频网站在线观看| 婷婷精品进入| 国产私拍一区| 日韩美女在线| 国内伊人久久久久久网站视频| 黄网在线观看| 欧美成人精精品一区二区频| 日本中文字幕久久| 亚洲美女偷拍久久| a级在线免费观看| 激情综合五月婷婷| 337p粉嫩大胆噜噜噜鲁| 久久电影院7| 国产伦精品一区二区三区免 | 精品日本一区二区三区在线观看| 日韩精品免费观看视频| 欧美激情影音先锋| www.亚洲资源| 日韩精品在线看| 99在线观看免费| 在线观看免费视频综合| 免费在线视频观看| 国产精品久久久久久久久免费桃花 | 97成人在线免费视频| 97偷自拍亚洲综合二区| 久久综合一区二区三区| 久久伊人影院| 国产玖玖精品视频| 欧美一区国产| 国模私拍一区二区三区| 国产视频中文字幕在线观看| 亚洲欧美日韩精品久久亚洲区| 亚洲精品无码久久久| 欧美精品久久一区| 中文字幕日韩国产| 岛国av一区二区在线在线观看| 欧美精品乱码视频一二专区| 国产精品毛片久久久久久| 精品人妻一区二区三区香蕉 | 欧美激情国产日韩| 亚洲精品观看| 亚洲一区二区三区成人在线视频精品| 日韩成人动漫| 欧美自拍大量在线观看| 蜜桃视频在线网站| 久久欧美在线电影| 日韩另类在线| 欧美日本中文字幕| 婷婷av在线| 欧美精品一区二区免费| 国产视频在线播放| 日韩日本欧美亚洲| 免费av在线网址| 色999日韩欧美国产| av一区在线观看| 在线免费观看羞羞视频一区二区| 青青草在线播放| 亚洲精品在线看| 日本视频在线观看一区二区三区| 日韩国产欧美精品一区二区三区| 人妻91麻豆一区二区三区| 精品成人免费观看| 六月丁香综合网| 亚洲国产欧美精品| 无码国产精品一区二区免费16| 精品国产一区久久| 天天色综合久久| 亚洲天堂av在线免费观看| 久久久久国产精品嫩草影院| 日韩av一区二| 日韩精品一区二区三区视频| 久久人人爽人人爽人人| 亚洲一区av在线| 国产对白videos麻豆高潮| 亚洲成a人片在线不卡一二三区| 久一视频在线观看| 第一福利永久视频精品| 特级毛片www| 欧美在线观看视频一区二区| 伊人成人在线观看| 在线综合视频播放| 黄色一级大片在线免费看国产| 亚洲国产91精品在线观看| 午夜av免费在线观看| 亚洲欧美日韩一区二区三区在线| 国产一级片在线播放| 日韩视频精品在线| 影音先锋男人资源在线| 国内揄拍国内精品| 99久久久国产精品免费调教网站| 国产自产女人91一区在线观看| 91嫩草国产线观看亚洲一区二区| 成人黄动漫网站免费| 亚洲精品一级二级三级| 在线视频精品一区| 亚洲东热激情| 久久久久久三级| 国产乱码一区二区三区| 变态另类丨国产精品| 中文字幕乱码日本亚洲一区二区 | 亚洲a级黄色片| 成人在线视频一区| 亚洲综合欧美综合| 亚洲最新视频在线播放| 91视频久久久| 日韩三级在线免费观看| 蜜桃成人在线视频| 欧美高清电影在线看| 久久人体大尺度| 99精品国产一区二区| 精品一区免费| 裸体裸乳免费看| 久久久久久亚洲精品杨幂换脸| 日本高清免费在线视频| 久久夜色精品国产噜噜av| 丁香花五月激情| 在线亚洲高清视频| 免费观看的毛片| 久久精品成人欧美大片| 新版的欧美在线视频| 亚洲精品欧美一区二区三区| 欧美精品一区二区三区中文字幕 | 久久美女性网| 国产吃瓜黑料一区二区| 国产精品国产成人国产三级| 日韩在线视频免费播放| 5566中文字幕一区二区电影| 福利小视频在线观看| 欧美激情亚洲国产| 成人永久在线| 一区二区三区电影| 老司机精品导航| bl动漫在线观看| 曰韩精品一区二区| 国产一区二区女内射| 亚洲视频自拍偷拍| 少妇视频一区| 国外成人在线视频网站| 中国精品18videos性欧美| 一本色道久久亚洲综合精品蜜桃 | 日韩av无码中文字幕| 日韩一区二区三区免费看 | 亚洲日本中文字幕区| 国模私拍一区二区| 亚洲欧美日韩高清| 亚洲一区站长工具| 久久综合狠狠综合久久综青草| 亚洲特级毛片| 国产清纯白嫩初高中在线观看性色| 亚洲欧美中日韩| 中文字幕日本人妻久久久免费 | 日韩高清中文字幕一区| 玖草视频在线观看| 亚洲一二三专区| 亚洲av综合色区无码一区爱av| www.久久撸.com| 精品福利在线| 亚洲欧洲在线一区| 日本网站在线观看一区二区三区| 白白色免费视频| 91高清视频在线| 国产视频精选在线| 国产精品亚洲激情| 久久精品不卡| 99九九99九九九99九他书对| 亚洲婷婷综合久久一本伊一区 | 亚洲国产成人精品久久| www.51av欧美视频| 精品欧美日韩在线| 欧美专区一区二区三区| 精品无码一区二区三区| 欧美色另类天堂2015| 毛片在线能看| 国产成人亚洲综合91| 日韩在线观看| 中文字幕免费高清在线| 亚洲欧洲精品一区二区三区不卡| 国产精品自拍电影| 欧美日韩成人精品| 欧美日韩一区二区三区在线电影| 久在线观看视频| 久久久亚洲欧洲日产国码αv| 免费看一级视频| 这里只有精品在线播放| 四虎精品永久免费| 400部精品国偷自产在线观看| 懂色中文一区二区在线播放| 可以在线观看av的网站| 国产香蕉97碰碰久久人人| 老司机精品视频网| 成人区一区二区| www国产精品av| 亚洲一区二区影视| 久久99精品久久久久久噜噜| 麻豆一区一区三区四区| 中文字幕第21页| 一区二区三区国产精品| 天堂v视频永久在线播放| 国产日韩在线精品av| 亚洲区第一页| 一级免费黄色录像| 精品电影一区二区| 日本电影久久久| 日本福利视频在线| 亚洲视频狠狠干| 亚洲欧美日韩免费| 91亚洲精品一区| 久久青草久久| 国产精彩视频在线| 在线观看国产欧美| 精品久久ai电影| 性生活免费在线观看| 岛国av午夜精品| 欧美videosex性欧美黑吊| 日韩精品欧美专区| 成人听书哪个软件好|