最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#溫故而知新系列教程之閉包

 更新時間:2018年05月19日 11:18:26   作者:RstarYan  
閉包是將一些執(zhí)行語句的封裝,可以將封裝的結(jié)果像對象一樣傳遞,在傳遞時,這個封裝依然能夠訪問到原上下文。下面這篇文章主要給大家介紹了關(guān)于C#中閉包的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

閉包的由來

形成閉包有一些值得總結(jié)的非必要條件:

1、嵌套定義的函數(shù)。

2、匿名函數(shù)。

3、將函數(shù)作為參數(shù)或者返回值。

4、在.NET中,可以通過匿名委托形成閉包:函數(shù)可以作為參數(shù)傳遞,也可以作為返回值返回,或者作為函數(shù)變量。而在.NET中,這都可以通過委托來實現(xiàn)。這些是實現(xiàn)閉包的前提。

要說閉包的由來就不得不先說下函數(shù)式編程了。近幾年函數(shù)式編程也是比較火熱,我們先來看看函數(shù)式編程的一些基本的特性這個有助于我們理解閉包的由來。

 函數(shù)式編程

函數(shù)式編程是一種編程模型,他將計算機(jī)運算看做是數(shù)學(xué)中函數(shù)的計算,并且避免了狀態(tài)以及變量的概念。這里很明顯的指出了函數(shù)式編程中最重要的就是函數(shù)而且是數(shù)學(xué)中的函數(shù),比如f(x),數(shù)學(xué)中的函數(shù)最大的特點就是只要是同樣的參數(shù)x那么我的結(jié)果必定是相等的,也就是說我們函數(shù)的返回值只是依賴于參數(shù)而不依賴于其他狀態(tài)(比如js中的全局變量就是一個干擾因素);后一句中說避免變量的概念,這句話如果從函數(shù)式編程來說不太恰當(dāng),因為這句話中的函數(shù)意思還是我們在編程語言中所使用的變量也就是一個存儲單元,而在函數(shù)式編程中變量卻是數(shù)學(xué)中變量的定義是一個值得名稱。比如,我們最基本的賦值等式 x = x+1,讓我們程序員看這是一個簡單的賦值代碼,而讓學(xué)數(shù)學(xué)的人來說這個等式是根本不成立的。 所以我們在函數(shù)式編程中是不允許多次賦值的。而這一句話也是講述了函數(shù)式編程好處的最主要的原因:

第一點、函數(shù)的結(jié)果只依賴于參數(shù)而不依賴其他狀態(tài),這樣寫的代碼很容易進(jìn)行推理不容易發(fā)生錯誤,極大的方便的單元測試和調(diào)試。

第二點、因為不可變性和無狀態(tài),那么我們在處理多個線程之間就不用擔(dān)心資源的爭奪,不需要用鎖來保存狀態(tài)。

高階函數(shù)

函數(shù)式編程中函數(shù)是一等公民,和我們的口號 "萬物皆對象"有點相似,在函數(shù)式編程中,我們努力用函數(shù)來表達(dá)所有的事情,當(dāng)然我們也需要函數(shù)可以傳過來傳過去這就是高階函數(shù),也就是把函數(shù)作為參數(shù)或者返回值,繼而實現(xiàn)復(fù)用,這樣即是可以把復(fù)用的粒度降到函數(shù)。C#語言中也有類似的東西--委托,當(dāng)然C#中的函數(shù)跟函數(shù)式編程中的就不一樣了,但是有吸收一些函數(shù)式編程語言中的特性,比如C#中l(wèi)amda,Linq。

關(guān)于函數(shù)式編程博客園有很多很好的文章介紹我就不詳說了,接下來就是引出我們今天的主題--閉包。

因為函數(shù)式編程的基礎(chǔ)就是Lambda演算,所以這一節(jié)演算我們用Lambda演算來帶出我們的主題,關(guān)于這個演算我也懂得不是太多,想要入門的同學(xué)可以看看這個  點這里

首先定義一個簡單的演算

    λx.λy.x+y

如果x為1 y為2 演算過程則為

  ((λx.λy.x+y)1)2=(λy.1+y)2=(1+2)=3

接下來我們用到高階函數(shù)

   λy . (λx . x + y)

演算過程:

  ((λy . (λx . x + y))1)2=((λx . x + 1))2 = (2+1)=3

可以看到這個演算中外層函數(shù)使用的是內(nèi)層函數(shù),也就是說使用是一個函數(shù)作為了計算結(jié)果。OK ,我們把內(nèi)層函數(shù)單獨拿出來,(λx . x + y),可以很明顯的看到如果脫離的上下文呢,我們的y是沒有值的,也就是y是沒有綁定的,也可以說y對于我們這個函數(shù)是自由的! 如果在函數(shù)式編程中,在外層函數(shù)執(zhí)行完畢之后我們的y變量就應(yīng)該被銷毀,那么如果我們在內(nèi)層函數(shù)中如果還需要用到y(tǒng)的話怎么辦呢? 對于這個問題,設(shè)計者則做了其他的處理:如果一個函數(shù)返回另一個函數(shù),而被返回函數(shù)又需要外層函數(shù)的變量時,不會立即釋放這個變量,而是允許被返回的函數(shù)引用這些變量。支持這種機(jī)制的語言稱為支持閉包機(jī)制,而這個內(nèi)部函數(shù)連同其自由變量就形成了一個閉包(這句話是摘自其他博客,自己難得整理文字。。。)。這就是我們閉包的由來,而我們其他的語言如果有用到函數(shù)式編程的思想,并且允許函數(shù)來進(jìn)行傳遞就會遇到類似的問題,所以各個語言就需要用其自己的方式來實現(xiàn)閉包!

C#中閉包的實現(xiàn)

從上一節(jié)我們也就是能總結(jié)出閉包其實就是要執(zhí)行并且包含自由變量的代碼塊(由于自由變量被包含在代碼塊中,這些自由變量以及它們引用的對象沒有被釋放)和為自由變量提供綁定的計算環(huán)境的一個結(jié)合。

然后進(jìn)入我們的C#編程時刻了,我們就用簡單的例子來實現(xiàn),并且查看編譯器生成的代碼 看看C#中是怎么實現(xiàn)閉包,畢竟我們也是有委托的 。。。

首先寫一個簡單得不能在簡單的代碼   

using System;

namespace closure
{
 class Program
 {
 static void Main(string[] args)
 {
 Console.WriteLine(test(1)(2));
 Console.ReadKey();
 }

 public static Func<int,int> test(int x)
 {
 //作用域1
 return (y) => 
 {
 //作用域2
 return x + y;
 };
 }
 }
}

可以看到我們test的方法中傳入變量x的作用域是在1 在執(zhí)行匿名函數(shù)的時候應(yīng)該是已經(jīng)釋放在作用域2就不應(yīng)該存在了,而我們卻能準(zhǔn)確的得到計算結(jié)果   

說明我們的變量x確實在作用域2中還存在,接下來我們看看編譯器幫我們做了什么事情,

 

可以看到我們的test方法中多了一個對象 <>c__DisplayClass1_0  class_;這個東西的具體定義是啥?

 

這個很明顯了,其實閉包只是編譯器幫我們把自由變量封裝到了一個對象中供我們作用域外使用,那我們?nèi)绻サ糇饔糜?中使用x變量呢?

 

編譯器原來為了自由變量維護(hù)的對象沒了 。。。結(jié)果在意料之中。

OK,這篇文章就到此結(jié)束了,關(guān)于閉包是python中啊 js中啊 或者C#中得用處我就不細(xì)說了

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • .net實現(xiàn)序列化與反序列化實例解析

    .net實現(xiàn)序列化與反序列化實例解析

    這篇文章主要介紹了.net實現(xiàn)序列化與反序列化實例解析,需要的朋友可以參考下
    2014-08-08
  • C#在后臺運行操作(BackgroundWorker用法)示例分享

    C#在后臺運行操作(BackgroundWorker用法)示例分享

    BackgroundWorker類允許在單獨的專用線程上運行操作。如果需要能進(jìn)行響應(yīng)的用戶界面,而且面臨與這類操作相關(guān)的長時間延遲,則可以使用BackgroundWorker類方便地解決問題,下面看示例
    2013-12-12
  • C#創(chuàng)建控制Windows服務(wù)

    C#創(chuàng)建控制Windows服務(wù)

    這篇文章介紹了C#創(chuàng)建和控制Windows服務(wù)的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • VB.NET中Caching的使用方法

    VB.NET中Caching的使用方法

    Caching緩存,就是將一些生成代價比較大的常用數(shù)據(jù),保存起來重用。一般數(shù)據(jù)都保存在內(nèi)存中,因為從內(nèi)存中讀取數(shù)據(jù)比從數(shù)據(jù)庫等其他地方要快。
    2013-04-04
  • 淺談C#指針問題

    淺談C#指針問題

    在C#中,有時候希望通過指針來操作內(nèi)存,這樣可以提高效率。我們可以用unsafe關(guān)鍵字修飾含有指針操作的程序段
    2016-01-01
  • ASP.NET C#中Application的用法教程

    ASP.NET C#中Application的用法教程

    這篇文章主要給大家介紹了關(guān)于ASP.NET C#中Application的用法,在介紹Application的用法之前,先給大家介紹了Session的用法供大家參考學(xué)習(xí),文中介紹的非常詳細(xì),需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-05-05
  • C# webclient中文亂碼問題解決方法

    C# webclient中文亂碼問題解決方法

    本文介紹使用webclient抓取遠(yuǎn)程頁面出現(xiàn)亂碼的處理方法,希望對大家有所幫助。
    2016-05-05
  • C#中使用?record?的好處和最佳場景

    C#中使用?record?的好處和最佳場景

    這篇文章主要介紹了C#中使用?record?的好處,使用?record?類型的主要好處包括簡潔的語法、自動生成的成員、基于值的相等性、非破壞性復(fù)制、解構(gòu)支持、繼承支持和與模式匹配的良好集成,需要的朋友可以參考下
    2024-07-07
  • C#實現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法

    C#實現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法

    眾所周知R軟件功能非常強(qiáng)大,可以很好的進(jìn)行各類統(tǒng)計,并能輸出圖形。下面介紹一種R語言和C#進(jìn)行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細(xì),需要的朋友可以參考下。
    2017-02-02
  • C#搜索文字在文件及文件夾中出現(xiàn)位置的方法

    C#搜索文字在文件及文件夾中出現(xiàn)位置的方法

    這篇文章主要介紹了C#搜索文字在文件及文件夾中出現(xiàn)位置的方法,涉及C#針對文件及文件夾遍歷與查找的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08

最新評論

石狮市| 从江县| 南城县| 邯郸县| 张家口市| 灵宝市| 宜黄县| 海门市| 瑞昌市| 无锡市| 正宁县| 贵州省| 阿尔山市| 邯郸县| 济宁市| 绩溪县| 奇台县| 孝感市| 城固县| 昌乐县| 永德县| 邵武市| 伊宁县| 西乌| 南木林县| 乾安县| 绵阳市| 于田县| 沙田区| 安多县| 冷水江市| 丹棱县| 修文县| 郯城县| 枞阳县| 通海县| 隆子县| 漳浦县| 依兰县| 军事| 高台县|