<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      Linq快速入門——Lambda表達(dá)式的前世今生

      Lambda表達(dá)式其實(shí)并不陌生,他的前生就是匿名函數(shù),所以要談Lambda表達(dá)式,就不得不談匿名函數(shù),要談匿名函數(shù),那又要不得不談委托。

      何為委托

      委托非常好理解,類似于C++里面的函數(shù)指針(指向了一個(gè)方法),并且委托約束了待指向方法的簽名(由返回類型和參數(shù)組成)。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      namespace 委托Test
      {
          delegate bool FilterDelegate(int i);
          class Program
          {
              static void Main(string[] args)
              {
                  int[] array = { 1, 2, 3, 5, 6, 6, 7, 8, 9 };
                  List<int> newList = MyFilter(array,FilterOdd);
                  foreach (int item in newList)
                  {
                      Console.WriteLine(item);
                  }
                  Console.ReadKey();
      
              }
              static List<int> MyFilter(int[] array, FilterDelegate filter)
              {
                  List<int> list = new List<int>();
                  for (int i = 0; i < array.Length; i++)
                  {
                      if (filter(i))
                      {
                          list.Add(i);
                      }
                  }
                  return list;
              }
              /// <summary>
              /// 偶數(shù)
              /// </summary>
              /// <param name="i"></param>
              /// <returns></returns>
              static bool FilterEven(int i)
              {
                  return i % 2 == 0;
              }
              /// <summary>
              /// 奇數(shù)
              /// </summary>
              /// <param name="i"></param>
              /// <returns></returns>
              static bool FilterOdd(int i)
              {
                  return i % 2 == 1;
              }
          }
      }

      對(duì)于上面這個(gè)Demo可以看出,我需要定義了兩個(gè)方法(FilterOdd,F(xiàn)ilterEven),讓我的委托變量指向這兩個(gè)方法。但有時(shí)候申明方法很麻煩,還要考慮方法名稱不重復(fù),所以對(duì)于一些我們只使用一次的方法,完全沒(méi)有必要單獨(dú)為其申明,使用匿名方法即可(C# 2.0為程序員提供了匿名方法),大大簡(jiǎn)化了操作

      匿名方法

      //例如
      delegate void Del(int x);
      ....
      Del d = delegate(int k) { /* ... */ };

      所以上面例子小小改動(dòng)一下即可:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      namespace 委托Test
      {
          delegate bool FilterDelegate(int i);
          class Program
          {
              static void Main(string[] args)
              {
                  int[] array = { 1, 2, 3, 5, 6, 6, 7, 8, 9 };
                  //使用匿名方法來(lái)求偶數(shù)
                  List<int> newList = MyFilter(array, delegate(int i) {
      
                      return i % 2 == 0;
                  });
               
                  foreach (int item in newList)
                  {
                      Console.WriteLine(item);
                  }
                  Console.ReadKey();
      
              }
              static List<int> MyFilter(int[] array, FilterDelegate filter)
              {
                  List<int> list = new List<int>();
                  for (int i = 0; i < array.Length; i++)
                  {
                      if (filter(i))
                      {
                          list.Add(i);
                      }
                  }
                  return list;
              }
          }
      }

      Lambda表達(dá)式特性

      • C# 2.0中加入的匿名方法,簡(jiǎn)化了我們編寫事件處理函數(shù)的工作,使我們不再需要單獨(dú)聲明一個(gè)函數(shù)來(lái)與事件綁定,只需要使用delegate關(guān)鍵字在線編寫事件處理代碼。
      • 而C# 3.0則更進(jìn)一步,通過(guò)Lambda表達(dá)式,我們可以一種更為簡(jiǎn)潔方式編寫事件處理代碼,新的Lambda事件處理代碼看上去就像一個(gè)計(jì)算表達(dá)式,它使用"=>"符號(hào)來(lái)連接事件參數(shù)和事件處理代碼。我可以這樣寫:SomeEvent += 事件參數(shù) => 事件處理代碼;

      所以上面代碼稍稍修改后,用Lambda表達(dá)式來(lái)替換匿名方法:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      namespace 委托Test
      {
          delegate bool FilterDelegate(int i);
          class Program
          {
              static void Main(string[] args)
              {
                  int[] array = { 1, 2, 3, 5, 6, 6, 7, 8, 9 };
                  //使用Lambda表達(dá)式來(lái)求偶數(shù)
                  List<int> newList = MyFilter(array, i => i % 2==0);
               
                  foreach (int item in newList)
                  {
                      Console.WriteLine(item);
                  }
                  Console.ReadKey();
      
              }
              static List<int> MyFilter(int[] array, FilterDelegate filter)
              {
                  List<int> list = new List<int>();
                  for (int i = 0; i < array.Length; i++)
                  {
                      if (filter(i))
                      {
                          list.Add(i);
                      }
                  }
                  return list;
              }
          }
      }

      注意:

      • 使用Lambda表達(dá)式,"=>"之前為參數(shù)列表,如果有多個(gè)參數(shù),則不能省略括號(hào),比如:(s,e)=>....
      • 如果方法有返回值,并且處理代碼只有一行,可以簡(jiǎn)寫成i=>i%2==0,等價(jià)于i=>{return i%2==0},反之對(duì)于有多行的處理代碼,則不能簡(jiǎn)寫,必須寫完整,比如:(s,e)=>{...程序代碼塊...}

      我們?cè)賮?lái)看看System.Linq名稱空間下的擴(kuò)展方法有什么特征:

      第一個(gè)參數(shù)為擴(kuò)展方法,我已經(jīng)在前一篇文章《Linq快速入門——擴(kuò)展方法》里提到了,我不做具體解釋了,簡(jiǎn)單來(lái)說(shuō)創(chuàng)建擴(kuò)展方法就是這四步:

      • 創(chuàng)建一個(gè)名為MyHelper的類,約定了此類中的方法均是擴(kuò)展方法。注意這個(gè)類必須是靜態(tài)類(Static)
      • 擴(kuò)展方法必須是Static靜態(tài)方法
      • 第一個(gè)參數(shù)為待擴(kuò)展的類型,前面標(biāo)注this
      • 如果MyHelper在一個(gè)類庫(kù)中,記得對(duì)其添加引用using相關(guān)名稱空間

      對(duì)于第二個(gè)參數(shù):System.Func<TSource, bool> predicate),我們?cè)賮?lái)深究下。

      Fun<T,TResult>  and  Action<T>

      • Fun<T,TResult>:此委托封裝一個(gè)具有一個(gè)參數(shù)并返回 TResult 參數(shù)指定的類型值的方法。所以在使用 Func<T, TResult> 委托時(shí),不必顯式定義一個(gè)封裝只有一個(gè)參數(shù)的方法并且其返回類型TResut委托
      • Action<T>:此委托封裝一個(gè)方法,該方法只有一個(gè)參數(shù)并且不返回值。所以在使用 Action<T> 委托時(shí),不必顯式定義一個(gè)封裝只有一個(gè)參數(shù)的方法(并且不能返回值)的委托。 

       所以再對(duì)上面的Filter進(jìn)行改進(jìn):

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      namespace 委托Test
      {
          //delegate bool FilterDelegate(int i);
          class Program
          {
              static void Main(string[] args)
              {
                  int[] array = { 1, 2, 3, 5, 6, 6, 7, 8, 9 };
                  //使用匿名方法來(lái)求偶數(shù)
                  //List<int> newList = MyFilter(array, delegate(int i) {
      
                  //    return i % 2 == 0;
                  //});
                  //使用Lambda表達(dá)式求偶數(shù)
                  List<int> newList = MyFilter(array, i => i % 2 == 0);
               
                  foreach (int item in newList)
                  {
                      Console.WriteLine(item);
                  }
                  Console.ReadKey();
      
              }
              //Func<int,bool>: 封裝了一個(gè)具有一個(gè)int參數(shù)并且返回類型為bool類型的方法
              static List<int> MyFilter(int[] array,Func<int,bool> filter)
              {
                  List<int> list = new List<int>();
                  for (int i = 0; i < array.Length; i++)
                  {
                      if (filter(i))
                      {
                          list.Add(i);
                      }
                  }
                  return list;
              }
          }
      }

      回顧,A Simple Lambda Demo

      •  下面Demo首先申明 Func<T, TResult> 變量,并為其分配了一個(gè) lambda 表達(dá)式。
      •  隨后將封裝此方法的委托(看下面實(shí)例)傳遞給Enumerable.Where、Enumerable.Order、 Enumerable.Select 方法,以將字符串?dāng)?shù)組中的字符串進(jìn)行處理。
      • ForEach 和 ForEach<T> 方法都采用 Action<T> 委托作為參數(shù)。 通過(guò)使用由委托封裝的方法,可以對(duì)數(shù)組或列表中的每個(gè)元素執(zhí)行操作
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      namespace LambdaDemo
      {
          class Program
          {
              static void Main(string[] args)
              {
                 
                  string[] names = {"Eyes","Voodoo","Tod","Chris","Christina","Maxisim" };
                  Func<string, bool> filter = s => s.Length > 5;
                  Func<string, string> order = s => s;
                  Func<string, string> operating = s => s.ToUpper();
      
                  IEnumerable<string> expr = names.Where(filter).OrderByDescending(order).Select(operating);
                  expr.ToList<string>().ForEach(i => Console.WriteLine(i));
                  Console.ReadKey();
      
              }
          }
      }

      Lambda表達(dá)式樹(shù)

      • 表達(dá)式樹(shù)表示樹(shù)狀數(shù)據(jù)結(jié)構(gòu)的代碼,樹(shù)狀結(jié)構(gòu)中的每個(gè)節(jié)點(diǎn)都是一個(gè)表達(dá)式,例如一個(gè)方法調(diào)用或類似 x < y 的二元運(yùn)算。
      • 并且你可以編譯和運(yùn)行由表達(dá)式樹(shù)所表示的代碼。這樣的優(yōu)勢(shì)就是表達(dá)式樹(shù)可以在運(yùn)行的時(shí)候編譯運(yùn)行,而且可以對(duì)lambda表達(dá)式進(jìn)行動(dòng)態(tài)修改。
      • 若要使用 API 創(chuàng)建表達(dá)式樹(shù),請(qǐng)使用 Expression 類。 此類包含創(chuàng)建特定類型的表達(dá)式樹(shù)節(jié)點(diǎn)的靜態(tài)工廠方法,例如,ParameterExpression(表示一個(gè)變量或參數(shù)),ConstantExpression(表示一個(gè)常量),MethodCallExpression(表示一個(gè)方法調(diào)用)。 ParameterExpression 、MethodCallExpression、ConstantExpression 以及其他表達(dá)式特定的類型也在 System.Linq.Expressions 命名空間中定義。 這些類型派生自抽象類型 Expression。

      例如將表達(dá)式(Price-5)*Count*Rebate表示成一棵二叉樹(shù)可以用以下方式表達(dá):

       

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Linq.Expressions;
      
      namespace Lambda表達(dá)式樹(shù)
      {
          class Program
          {
              static void Main(string[] args)
              {
                  //計(jì)算(Price-5)*Count*Rebate
                  ParameterExpression paraPrice = Expression.Parameter(typeof(decimal),"price");
                  ConstantExpression constant = Expression.Constant(5m,typeof(decimal));
                  BinaryExpression result1 = Expression.Subtract(paraPrice, constant);
      
                  ParameterExpression paraCount = Expression.Parameter(typeof(decimal),"count");
                  ParameterExpression paraRebate = Expression.Parameter(typeof(decimal),"rebate");
                  BinaryExpression result2 = Expression.Multiply(paraCount,paraRebate);
      
                  BinaryExpression result3 = Expression.Multiply(result1,result2);
                  Expression<Func<decimal, decimal, decimal, decimal>> totalPrice = Expression.Lambda<Func<decimal, decimal, decimal, decimal>>(result3,paraPrice,paraCount,paraRebate);
                  Func<decimal, decimal, decimal, decimal> myFun = totalPrice.Compile();
                  Console.WriteLine(myFun(125m,10m,0.5m));
                  Console.ReadKey();
      
              }
            
          }
      }

      分析表達(dá)式樹(shù)

      Expression<TDelegate> 類型提供 Compile 方法,該方法將表達(dá)式樹(shù)表示的代碼編譯成一個(gè)可執(zhí)行委托。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Linq.Expressions;
      
      
      namespace ConsoleApplication2
      {
          class Program
          {
              static void Main(string[] args)
              {
               
                  Expression<Func<int, int>> f1 = x => x + 1;
                  //f1(1)//...錯(cuò)誤,必須將表達(dá)式樹(shù)表示的代碼編譯成一個(gè)可執(zhí)行委托
                  Func<int, int> f2 = f1.Compile();
                  Console.WriteLine(f2(2));
                  Console.ReadKey();
              }
          }
      }

      總結(jié)

      未完,持續(xù)更新中

      posted @ 2012-08-27 17:25  木宛哥說(shuō)編程  閱讀(23732)  評(píng)論(60)    收藏  舉報(bào)
      multifunction lasers
      訪問(wèn)人數(shù)

      主站蜘蛛池模板: 麻豆精品在线| 亚洲激情一区二区三区在线| 国产乱人伦无无码视频试看| 午夜精品久久久久久久爽 | 台湾佬自拍偷区亚洲综合 | 91网站在线看| 久久热这里只有精品66| 人妻18毛片A级毛片免费看 | 亚洲无码精品视频| 欧美性xxxxx极品| 国产精品黄在线观看免费| 国产一区精品综亚洲av| 亚洲精品久荜中文字幕| 中文字幕久久波多野结衣av| 99视频30精品视频在线观看| 亚洲人成电影在线天堂色| 国产精品美女免费无遮挡| 免费无码黄网站在线观看| 亚洲精品不卡无码福利在线观看| 粉嫩国产av一区二区三区| 亚洲欧美自偷自拍视频图片| 口爆少妇在线视频免费观看| 熟妇的奶头又大又长奶水视频 | 国产老熟女国语免费视频| 狠狠躁夜夜躁人人爽天天古典| 亚洲一区二区三区在线| 亚洲av色香蕉一区二区三| 中文精品无码中文字幕无码专区| 婷婷久久综合九色综合88| 国产黄色一区二区三区四区| 色狠狠色婷婷丁香五月| 欧美色欧美亚洲高清在线观看| 一区二区三区四区激情视频| 国产免费午夜福利在线播放| 精品国产综合成人亚洲区| 最新国产精品亚洲| 亚洲精品美女一区二区| 国产一级二级三级毛片| 亚洲av激情综合在线| 在线观看中文字幕国产码| 日韩精品一区二区av在线|