国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

[.net 面向?qū)ο蟪绦蛟O(shè)計(jì)進(jìn)階] (5) Lamda表達(dá)式(一) 創(chuàng)建委托

2019-11-17 02:11:20
字體:
供稿:網(wǎng)友

[.net 面向?qū)ο蟪绦蛟O(shè)計(jì)進(jìn)階] (5) Lamda表達(dá)式(一) 創(chuàng)建委托

[.net 面向?qū)ο蟪绦蛟O(shè)計(jì)進(jìn)階] (5) Lamda表達(dá)式(一) 創(chuàng)建委托

本節(jié)導(dǎo)讀:

通過學(xué)習(xí)Lambda表達(dá)式,學(xué)會(huì)創(chuàng)建委托和表達(dá)式目錄樹,深入了解Lambda的特性,讓你的代碼變的更加清晰、簡(jiǎn)潔、高效。

讀前必備:

本節(jié)學(xué)習(xí)前,需要掌握以下知識(shí):

A.泛型 (請(qǐng)參考[.net 面向?qū)ο缶幊袒A(chǔ)]  (18) 泛型)

B.Linq基礎(chǔ)(請(qǐng)參照[.net 面向?qū)ο缶幊袒A(chǔ)] (19)LINQ基礎(chǔ))

C.Linq使用(請(qǐng)參照[.net 面向?qū)ο缶幊袒A(chǔ)](20)LINQ使用)

D.委托 (請(qǐng)參照[.net 面向?qū)ο缶幊袒A(chǔ)]  (21) 委托)

E.事件 (請(qǐng)參照[.net 面向?qū)ο缶幊袒A(chǔ)] (22) 事件)

通過《.net面向?qū)ο缶幊袒A(chǔ)》系列中相關(guān)介紹,我們已經(jīng)初步使用過了Lambda表達(dá)式進(jìn)行Linq查詢,這節(jié)我們主要深入了解Lambda表達(dá)式。

1. 關(guān)于Lambda

Lambda表達(dá)式是一種可用于創(chuàng)建委托或表達(dá)式目錄樹類型的匿名函數(shù)。

以上是微軟對(duì)Lambda表達(dá)式的定義。從這個(gè)定義中,我們可以看出,Lambda的存在,主要做兩件事:

A.創(chuàng)建委托(Delegate)

B.創(chuàng)建表達(dá)式樹(ExPRessionTree)

此外,Lambda表達(dá)式的本質(zhì)就是匿名方法(或叫匿名函數(shù))。

后面面我們分別從這兩個(gè)方法入手,進(jìn)一步學(xué)習(xí)Lambda帶我給我們的便利。

2.Lambda表達(dá)式

Lambda表達(dá)式的構(gòu)成如下:

零個(gè)參數(shù):()=>expr

一個(gè)參數(shù):(param)=>expr或param=>expr

多個(gè)參數(shù):(param-list)=>expr

所有Lambda表達(dá)式都使用Lambda運(yùn)算符=>,該運(yùn)算符讀作"goesto"

當(dāng)參數(shù)只有一個(gè)時(shí),右邊的括號(hào)可以省略。

下面是寫法舉例:

//零個(gè)參數(shù)() => MethodName()//一個(gè)參數(shù)(x) => x+xX=>x+x//兩個(gè)及以上參數(shù)(m,n) => m.Length>n//顯式類型參數(shù)(int x,string y)=>y.Length>x

上面的示例中,其中顯式類型參數(shù),是當(dāng)編譯器無法推斷其參數(shù)類型時(shí),可以顯式的定義參數(shù)類型。

3.Lambda語(yǔ)句

Lambda語(yǔ)句和Lambda表達(dá)式類似,只是右邊部分寫在{}中

Lambda語(yǔ)句構(gòu)成如下:

(inputparameters)=>{statement;}

示例:

delegate void TestDelegate(string s);…TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };myDel("Hello");

4.異步Lambda(async和await)

我們通過在《.net面向?qū)ο缶幊袒A(chǔ)》中學(xué)習(xí),了解了事件本身也是一種特殊的委托,那么Lambda可用于創(chuàng)建委托也就是說同樣可以來創(chuàng)建事件。

下面看示例:

首先看一個(gè)普通按鈕點(diǎn)擊事件的實(shí)現(xiàn)及Lambda語(yǔ)句寫法

下面是普通寫法:

 this.myButton.Click += new System.EventHandler(this.myButton_Click);//事件通常委托寫法private void myButton_Click(object sender, EventArgs e){    MessageBox.Show("您好,我是按鈕點(diǎn)擊事件!");}

下面是Lambda寫法:

//事件Lambda語(yǔ)句寫法myButton.Click += (sender, e) => { MessageBox.Show("您好,我是按鈕點(diǎn)擊事件!這是Lambda語(yǔ)句寫法"); };

上面兩種寫法,我們?cè)谇懊娴恼鹿?jié)中已經(jīng)有很多例子了。

下面我們看一下異步的事件:

//異步事件普通寫法private async void asyncButton_Click(object sender, EventArgs e){    await MyMethodAsync();    MessageBox.Show("您好,我是按鈕點(diǎn)擊事件!異步的喲!");}async Task MyMethodAsync(){                await Task.Delay(1000);}

我們用Lambda來改寫上面的異步事件:

//異步事件Lambda寫法asyncButton.Click += async (sender, e) => { await MyMethodAsync();  MessageBox.Show("您好,我是按鈕點(diǎn)擊事件!異步的喲!這是Lambda語(yǔ)句寫法"); };async Task MyMethodAsync(){                await Task.Delay(1000);}

上面的異步事件,就是在事件委托階段使用async來表示這是一個(gè)異步的,在事件處理中階段使用await關(guān)鍵詞來指定一個(gè)異步方法。

Lambda語(yǔ)句寫法同樣是針對(duì)異步事件的簡(jiǎn)潔寫法,具有相同的效力。

5. 標(biāo)準(zhǔn)查詢運(yùn)算的Lambda表達(dá)式

5.1泛型委托使用Lambda

我們?cè)赱.net 面向?qū)ο缶幊袒A(chǔ)]  (21) 委托一節(jié)中說到了三種常用的泛型委托

Action(無返回值泛型委托)

Func(有返回值泛型委托)

predicate(返回值為bool型的泛型委托)

這節(jié)不再重復(fù)說明泛型委托,不熟悉泛型委托的小伙伴,請(qǐng)參考,我們只舉例說明泛型委托和它的Lambda寫法

//Action 無返回值類型的 泛型委托//匿名方法聲明及調(diào)用Action<int, int> act = delegate (int a, int b) {    Console.WriteLine(a + "+" + b + "=" + (a + b));};act(11, 22);//表達(dá)式聲明及調(diào)用Action<int, int> actLambda = (a, b) => { Console.WriteLine(a + "+" + b + "=" + (a + b)); };actLambda(111, 222);//Func 帶返回值的 泛型委托//匿名方法聲明及調(diào)用Func<int, int, string> acc = delegate (int a, int b) {    return (a + "+" + b + "=" + (a + b));};Console.WriteLine(acc(11, 22));//表達(dá)式聲明及調(diào)用Func<int, int, string> ac = (a, b) => { return (a + "+" + b + "=" + (a + b)); };Console.WriteLine(ac(111, 222));

5.2Linq中使用Lambda

關(guān)于在Linq中使用Lambda表達(dá)式,我們?cè)赱.net 面向?qū)ο缶幊袒A(chǔ)](20)LINQ使用有詳細(xì)說明了,不熟悉的小伙伴請(qǐng)參考,下面我們舉例說明幾種常用的Lambda查詢寫法。

5.2.1Count求數(shù)量

//查詢下列數(shù)中的奇數(shù) - Lambda寫法int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };int oddNumbers = numbers.Count(n => n % 2 == 1);Console.WriteLine("奇數(shù)有:"+oddNumbers.ToString()+ "個(gè),Lambda寫法");//查詢下列數(shù)中的奇數(shù) -Linq查詢寫法var oddNumbersFunc = (from num in numbers                        where num % 2 == 1                        select num                    ).Count();Console.WriteLine("奇數(shù)有:" + oddNumbersFunc.ToString() + "個(gè),Linq查詢寫法");

運(yùn)行結(jié)果如下:

5.2.2 TakeWhile滿足條件就返回集合

//TakeWhile只要滿足指定的條件就返回,在檢檢到number中的6時(shí),就返回,其中8 和9 不滿足條件,則返回 5 4 1 3 int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);Console.WriteLine("滿足條件就返回的數(shù)有:" + firstNumbersLessThan6.Count().ToString() + "個(gè),Lambda寫法");//第二個(gè)參數(shù)index表示n的索引位置string NewNumber = String.Empty;numbers.TakeWhile((n, index) => n >= index).ToList().ForEach(m=> NewNumber+=m +" ");Console.WriteLine("滿足條件就返回的數(shù)有:" + NewNumber + ",Lambda寫法");

運(yùn)行結(jié)果如下:

6. Lambda的類型推理

在編寫lambda時(shí),通常不必為輸入?yún)?shù)指定類型,因?yàn)榫幾g器可以根據(jù)lambda主體、參數(shù)的委托類型以及C#語(yǔ)言規(guī)范中描述的其他因素來推斷類型。對(duì)于大多數(shù)標(biāo)準(zhǔn)查詢運(yùn)算符,第一個(gè)輸入是源序列中的元素類型。因此,如果要查詢IEnumerable<Customer>,則輸入變量將被推斷為Customer對(duì)象,這意味著你可以訪問其方法和屬性:

//Lambda的類型推理List<MyClass> list = new List<MyClass>() {    new MyClass(){  at1 = "aaa", at2 = 2, at3 = DateTime.Now},    new MyClass{ at1 = "bbb", at2 = 5, at3 = DateTime.Parse("2015-06-07") },    new MyClass{ at1 = "aaa", at2 = 1, at3 = DateTime.Parse("2010-11-12")  }};            Console.WriteLine("at1為aaa的元素有:" + list.Where(m => m.at1 == "aaa").Count() + "個(gè),Lambda寫法");
class MyClass {    public  string at1 { get; set; }    public int at2 { get; set; }    public DateTime at3 { get; set; }}

運(yùn)行結(jié)果如下:

Lambda的一般規(guī)則如下:

A.Lambda包含的參數(shù)數(shù)量必須與委托類型包含的參數(shù)數(shù)量相同。

B.Lambda中的每個(gè)輸入?yún)?shù)必須都能夠隱式轉(zhuǎn)換為其對(duì)應(yīng)的委托參數(shù)。

C.Lambda的返回值(如果有)必須能夠隱式轉(zhuǎn)換為委托的返回類型。

請(qǐng)注意,lambda表達(dá)式本身沒有類型,因?yàn)槌R?guī)類型系統(tǒng)沒有“Lambda表達(dá)式”這一內(nèi)部概念。但是,有時(shí)以一種非正式的方式談?wù)搇ambda表達(dá)式的“類型”會(huì)很方便。在這些情況下,類型是指委托類型或lambda表達(dá)式所轉(zhuǎn)換到的 Expression類型。

7. Lambda表達(dá)式的變量范圍

我們?cè)赱.net 面向?qū)ο缶幊袒A(chǔ)]  (19)LINQ基礎(chǔ)一節(jié)中說到匿名方法時(shí)提到匿名方法可以引用滿園內(nèi)的外部變量,前面示例中也有提及。

下面我們看一個(gè)示例:

class Program{    static int num = 2;    static void Main(string[] args)    {        int num2 = 7;        //Lambda表達(dá)式的變量范圍        //相對(duì)以下表達(dá)式內(nèi)部,一個(gè)類的字段num和一個(gè)變量num2,下面測(cè)試在表達(dá)式內(nèi)部調(diào)用        int[] numbers2 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };        //我們對(duì)大于num小于num2的數(shù)求和        int sum = numbers2.Where(m => m > num && m < num2).Sum();        Console.WriteLine("大于num小于num2的和為:" + sum);        Console.ReadKey();    }}

下列規(guī)則適用于lambda表達(dá)式中的變量范圍:

A.捕獲的變量將不會(huì)被作為垃圾回收,直至引用變量的委托符合垃圾回收的條件。

B.在外部方法中看不到lambda表達(dá)式內(nèi)引入的變量。

C.Lambda表達(dá)式無法從封閉方法中直接捕獲ref或out參數(shù)。

D.Lambda表達(dá)式中的返回語(yǔ)句不會(huì)導(dǎo)致封閉方法返回。

E.如果跳轉(zhuǎn)語(yǔ)句的目標(biāo)在塊外部,則lambda表達(dá)式不能包含位于lambda函數(shù)內(nèi)部的goto語(yǔ)句、break語(yǔ)句或continue語(yǔ)句。同樣,如果目標(biāo)在塊內(nèi)部,則在lambda函數(shù)塊外部使用跳轉(zhuǎn)語(yǔ)句也是錯(cuò)誤的。

8.要點(diǎn):

本節(jié)主要說明了:

Lambda表達(dá)式在創(chuàng)建委托中的應(yīng)用;

Lambda表達(dá)式在Linq查詢中的應(yīng)用;

Lambda語(yǔ)句在異步事件中的應(yīng)用;

Lambda的兩個(gè)特性:類型推理和外部變量引用

下一節(jié),我們主要說明Lambda的另一個(gè)特點(diǎn),就是創(chuàng)建表達(dá)式目錄樹(ExpressionTree)。

==============================================================================================

返回目錄

<如果對(duì)你有幫助,記得點(diǎn)一下推薦哦,如有

有不明白或錯(cuò)誤之處,請(qǐng)多交流>

<對(duì)本系列文章閱讀有困難的朋友,請(qǐng)先看《.net面向?qū)ο缶幊袒A(chǔ)》>

<轉(zhuǎn)載聲明:技術(shù)需要共

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 腾冲县| 花垣县| 宣威市| 娄底市| 玛多县| 张北县| 靖西县| 长乐市| 东源县| 石台县| 留坝县| 红桥区| 浏阳市| 四会市| 大邑县| 宕昌县| 平安县| 彭山县| 天峻县| 汕尾市| 无棣县| 泽州县| 曲松县| 安阳县| 南丹县| 温泉县| 西吉县| 镇远县| 益阳市| 和田市| 富裕县| 兴安县| 平阳县| 云梦县| 舞钢市| 吉安县| 蒲城县| 青田县| 阜康市| 鄂托克旗| 栾城县|