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

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

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

        大家好,由于今天項(xiàng)目升級(jí),大家都在獲最新代碼,所以我又有時(shí)間在這里寫點(diǎn)東西,跟大家分享。

            在上一篇的文章中我介紹了一個(gè)dll,使大家在debug的時(shí)候可以可視化的看到ExpressionTree的Body和Parameter。今天這篇文章主要講一個(gè)問題——如何利用一個(gè)已有的表達(dá)式樹的body來構(gòu)建一個(gè)新的表達(dá)式樹。      不多說廢話,現(xiàn)在開始進(jìn)入正題。

            假設(shè)我們要寫一個(gè)像下面這樣的方法:

           

       public Func<stringbool> ReBuildExpression(Expression<Func<stringbool>> lambd0, Expression<Func<stringbool>> lambd1)

       

       

             這個(gè)方法的用意很簡單,就是把傳入的兩個(gè)參數(shù)為string類型,返回類型為bool的方法做一個(gè)且的關(guān)系,構(gòu)建出一個(gè)新的以string為參數(shù),返回類型為bool的方法。

             舉個(gè)例子,如果傳入的lambd0,lambd1為如下謂語表達(dá)式:

            

       Expression<Func<stringbool>> lambda0 = item => item.Length > 2;
                  Expression
      <Func<stringbool>> lambda1 = item => item.Length < 4;

       

       

            那么,我們希望ReBuildExpression這個(gè)方法返回的謂語表達(dá)式為item=>item.Length>2&&item.Length<4。

            通過上一篇的介紹我們知道,對于一個(gè)表達(dá)式樹來說,我們可以把它分為2部分——body和parameter,邏輯在body,參數(shù)在parameter,那么很自然的,我們想到采用如下方式來實(shí)現(xiàn)這個(gè)方法:

           

      代碼
              public Func<stringbool> ReBuildExpression(Expression<Func<stringbool>> lambd0, Expression<Func<stringbool>> lambd1)
              {
                  parameter 
      = Expression.Parameter(typeof(string), "name");
                  Expression left 
      = lambd0.Body;
                  Expression right 
      = lambd1.Body;
                  BinaryExpression expression 
      = Expression.AndAlso(left, right);
                  Expression
      <Func<stringbool>> lambda = Expression.Lambda<Func<stringbool>>(expression, parameter);
                  
      return lambda.Compile();
              }

       

              

        相信通過前幾篇的介紹大家已經(jīng)能大致看懂這段程序了,這段程序只是把傳入的兩個(gè)表達(dá)式樹做了一個(gè)且的關(guān)系,構(gòu)建出一個(gè)新的謂語表達(dá)式并傳出。

            那么,這段程序的運(yùn)行結(jié)果如何呢?

            大家如果調(diào)用這個(gè)方法,運(yùn)行程序就會(huì)發(fā)現(xiàn)程序會(huì)拋出一個(gè)異常:Lambda Parameter not in scope。

            這個(gè)異常字面的意思是Lambda參數(shù)不在作用范圍內(nèi),為什么會(huì)有這個(gè)異常呢?

            下面,請?jiān)试S我用一個(gè)例子來解釋這個(gè)問題。

            我們將一個(gè)表達(dá)式樹比作一輛2輪自行車,那么body就是自行車骨架,parameter就是2個(gè)車輪。

            好了,我們可以把上面代碼中的lambd0和lambd1看成2輛雙輪自行車。

            我們在代碼中想把這2輛雙輪自行車拼接成一輛3人騎的4輪自行車,所以我們寫了以下代碼:

            Expression left = lambd0.Body;
            Expression right 
      = lambd1.Body;

            注意!這就是問題的關(guān)鍵所在,這里我們只是引用了這2個(gè)自行車的骨架,而不是復(fù)制!我們希望構(gòu)造出的4輪自行車沒有任何骨架,這2句只是說想引用已有的2個(gè)骨架,但問題就來了,已有的自行車骨架還連接著lambd0和lambd1的車輪,并不能被新的自行車所用,我們必須按照已有的骨架復(fù)制出一個(gè)一模一樣的骨架才能被我們的新的4輪自行車所用。

            在這里截個(gè)lambda0的圖給大家看:

        

            這是用上一篇的工具看到的,大家注意看紅色框框中的部分,Body中的memberExpression是記錄了parameter的信息的,這就是問題所在。

            所以就有了下面的解決方案。

            首先,我們要在項(xiàng)目中加入一個(gè)新的文件——ExpressionVisitor.cs,這個(gè)文件是上一篇的dll中的一個(gè)源文件./Files/FlyEdward/ExpressionVisitor.zip

            大家可以從上面的鏈接中把它下載下來。我在這里粘貼這個(gè)類的聲明給大家看看

           

       public abstract class ExpressionVisitor
          {
              
      protected ExpressionVisitor()
              {
              }

              
      protected virtual Expression Visit(Expression exp)
              {

       

           大家在這里可以看到這個(gè)類是個(gè)抽象類,然后Visit的訪問權(quán)限也是protected。

           所以,我們必須再自己實(shí)現(xiàn)一個(gè)類,并且暴露出一個(gè)public的類來調(diào)用這個(gè)Visit方法。

           這里解釋一下,ExpressionVisitor這個(gè)類的設(shè)計(jì)初衷是修改表達(dá)式樹而并非復(fù)制表達(dá)式樹,所以才把類設(shè)計(jì)成了abstract的,并且visit還是protected的,目的就是要用戶自己實(shí)現(xiàn)一個(gè)子類,定義修改的規(guī)則,下面的鏈接是一個(gè)例子,把一個(gè)表達(dá)式樹中的所有“且”邏輯修改成“或”邏輯。

           http://msdn.microsoft.com/zh-cn/library/bb546136.aspx
           好了,接著我們的項(xiàng)目說,我們自己實(shí)現(xiàn)一個(gè)子類來調(diào)用visit方法來訪問并復(fù)制表達(dá)式樹。

          

      代碼
         public class ExpressionVisitorMy : ExpressionVisitor
          {
              
      public ParameterExpression Parameter
              {
                  
      get;
                  
      set;
              }

              
      public System.Linq.Expressions.Expression Modify(System.Linq.Expressions.Expression exp)
              {
                  
      return this.Visit(exp);
              }

              
      protected override Expression VisitParameter(ParameterExpression p)
              {
                  
      return Parameter;
              }
          }

       

       

       

       

       

           大家注意,在這個(gè)類里我們新增了一個(gè)Parameter屬性,我們可以把新的Parameter賦給這個(gè)屬性,而不要它去訪問以前的“車輪”。

           好了,接著,就可以實(shí)現(xiàn)之前的那個(gè)方法了:

          

      代碼
              public Func<stringbool> ReBuildExpression(Expression<Func<stringbool>> lambd0, Expression<Func<stringbool>> lambd1)
              {
                  ExpressionVisitorMy visitor 
      = new ExpressionVisitorMy();
                  ParameterExpression parameter 
      = Expression.Parameter(typeof(string), "name");
                  visitor.Parameter 
      = parameter;
                  Expression left 
      = visitor.Modify(lambd0.Body);
                  Expression right 
      = visitor.Modify(lambd1.Body);
                  BinaryExpression expression 
      = Expression.AndAlso(left, right);
                  Expression
      <Func<stringbool>> lambda = Expression.Lambda<Func<stringbool>>(expression, parameter);
                  
      return lambda.Compile();
              }

       

       

        大家注意:

        ParameterExpression parameter = Expression.Parameter(typeof(string), "name");
            visitor.Parameter 
      = parameter;
            這2句只是表示這個(gè)表達(dá)式樹對應(yīng)的參數(shù)類型為string,形參的名字是name。

            好,下面貼出Program中的完整代碼:

           

      代碼
      class Program 
          {
              
      static void Main(string[] args)
              {
                  List
      <string> names = new List<string> { "Cai""Edward""Beauty" }; 

                  Expression
      <Func<stringbool>> lambda0 = item => item.Length > 2;
                  Expression
      <Func<stringbool>> lambda1 = item => item.Length < 4;
                  Expression
      <Func<stringbool>> lambda2 = name => name.Length > 2 && name.Length < 3;

                  Program program 
      = new Program();
                  Func
      <stringbool> method = program.ReBuildExpression(lambda0, lambda1);

                  
                  var query 
      = names.Where(method);

                  
      foreach (string n in query)
                  {
                      Console.WriteLine(n);
                  }
                  Console.Read();
              }

              
      public Func<stringbool> ReBuildExpression(Expression<Func<stringbool>> lambd0, Expression<Func<stringbool>> lambd1)
              {
                  ExpressionVisitorMy visitor 
      = new ExpressionVisitorMy();
                  ParameterExpression parameter 
      = Expression.Parameter(typeof(string), "name");
                  visitor.Parameter 
      = parameter;
                  Expression left 
      = visitor.Modify(lambd0.Body);
                  Expression right 
      = visitor.Modify(lambd1.Body);
                  BinaryExpression expression 
      = Expression.AndAlso(left, right);
                  Expression
      <Func<stringbool>> lambda = Expression.Lambda<Func<stringbool>>(expression, parameter);
                  
      return lambda.Compile();
              }
              

          }

       

             這段程序的運(yùn)行結(jié)果就是輸出長度大于2,小于4的"Cai"。

         今天就跟大家分享到這里,下一篇中我將結(jié)合自己開發(fā)中遇到的問題,跟大家舉例講解一些表達(dá)式樹的應(yīng)用場景和今天講的ExpressionVisitor的應(yīng)用場景。希望大家能繼續(xù)關(guān)注。

      posted on 2010-12-06 16:00  Edward.Zhan  閱讀(3949)  評(píng)論(10)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产不卡一区二区三区视频| 樱桃熟了a级毛片| 377人体粉嫩噜噜噜| 无码综合天天久久综合网 | 人人人爽人人爽人人av| 久久精品高清一区二区三区| 男人猛躁进女人免费播放| 国产在线98福利播放视频| 两性午夜刺激性视频| 丰满人妻熟妇乱又仑精品| 高清有码国产一区二区| 免费无码成人AV片在线| AV无码免费不卡在线观看 | 色www视频永久免费| 免费人妻无码不卡中文18禁| 亚洲人精品午夜射精日韩| 日本一区二区三区四区黄色| 色婷婷久久综合中文久久一本| 亚洲嫩模喷白浆在线观看| 亚洲大尺度一区二区三区| 国产免费高清69式视频在线观看| 久久精品国产99国产精品亚洲| 好爽毛片一区二区三区四| 亚洲成在人线在线播放无码 | 久久天天躁夜夜躁狠狠 ds005.com | 一个人看的www免费高清视频| 色综合久久蜜芽国产精品| 亚洲av激情一区二区三区| 91中文字幕在线一区| 久久亚洲色www成人欧美| 亚洲女同性同志熟女| 国产精品日日摸夜夜添夜夜添无码| 成人午夜国产内射主播| 欧洲无码一区二区三区在线观看| 精品无套挺进少妇内谢| 熟女精品色一区二区三区| 久久人人爽人人爽人人片av| 日本一区二区三深夜不卡| 亚洲精品美女一区二区| 中国CHINA体内裑精亚洲日本| 一区二区三区成人|