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

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

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

      Util應(yīng)用程序框架公共操作類(十二):Lambda表達(dá)式公共操作類(三)

        今天在開發(fā)一個簡單查詢時,發(fā)現(xiàn)我的Lambda操作類的GetValue方法無法正確獲取枚舉類型值,以至查詢結(jié)果錯誤。

        我增加了幾個單元測試來捕獲錯誤,代碼如下。

           /// <summary>
              /// 測試值為枚舉
              /// </summary>
              [TestMethod]
              public void TestGetValue_Enum() {
                  var test1 = new Test1();
                  test1.NullableEnumValue = LogType.Error;
      
                  //屬性為枚舉,值為枚舉
                  Expression<Func<Test1, bool>> expression = test => test.EnumValue == LogType.Debug;
                  Assert.AreEqual( LogType.Debug.Value(), Lambda.GetValue( expression ) );
      
                  //屬性為枚舉,值為可空枚舉
                  expression = test => test.EnumValue == test1.NullableEnumValue;
                  Assert.AreEqual( LogType.Error, Lambda.GetValue( expression ) );
      
                  //屬性為可空枚舉,值為枚舉
                  expression = test => test.NullableEnumValue == LogType.Debug;
                  Assert.AreEqual( LogType.Debug, Lambda.GetValue( expression ) );
      
                  //屬性為可空枚舉,值為可空枚舉
                  expression = test => test.NullableEnumValue == test1.NullableEnumValue;
                  Assert.AreEqual( LogType.Error, Lambda.GetValue( expression ) );
      
                  //屬性為可空枚舉,值為null
                  test1.NullableEnumValue = null;
                  expression = test => test.NullableEnumValue == test1.NullableEnumValue;
                  Assert.AreEqual( null, Lambda.GetValue( expression ) );
              }

        單元測試成功捕獲了Bug,我打開Lambda操作類,準(zhǔn)備修改GetValue方法,代碼見Util應(yīng)用程序框架公共操作類(八):Lambda表達(dá)式公共操作類(二)

        面對GetValue雜亂無章的代碼,我頓時感覺無法下手,必須徹底重構(gòu)它。

        我之前也看過一些Lambda表達(dá)式解析的代碼和文章,基本都是使用NodeType來進(jìn)行判斷。我一直沒有使用這種方式,是因為NodeType數(shù)量龐大,并且多種NodeType可能轉(zhuǎn)換為同一種Expression類型。我當(dāng)時認(rèn)為用switch判斷NodeType工作量太大,所以直接采用As轉(zhuǎn)換為特定表達(dá)式,再判斷是否空值。

        我把這種山寨方法稱為瞎貓碰到死耗子,主要依靠單元測試來捕獲需求,通過斷點調(diào)試,我可以知道轉(zhuǎn)換為哪種特定表達(dá)式。這種方法在前期看上去貌似很有效,比判斷NodeType的代碼要少,但由于使用表達(dá)式的方式千差萬別,負(fù)擔(dān)越來越重,以至無法維護(hù)了。

        為了徹底重構(gòu)GetValue方法,我需要補(bǔ)充一點表達(dá)式解析的知識,我打開開源框架linq2db,仔細(xì)觀察他是如何解析的。終于看出點眉目,依靠NodeType進(jìn)行遞歸判斷。

        我以前只知道使用NodeType進(jìn)行判斷,但不知道應(yīng)該采用遞歸的方式,真是知其然不知其所以然。

        我對GetValue進(jìn)行了重構(gòu),代碼如下。

           /// <summary>
              /// 獲取值,范例:t => t.Name == "A",返回 A
              /// </summary>
              /// <param name="expression">表達(dá)式,范例:t => t.Name == "A"</param>
              public static object GetValue( Expression expression ) {
                  if ( expression == null )
                      return null;
                  switch ( expression.NodeType ) {
                      case ExpressionType.Lambda:
                          return GetValue( ( (LambdaExpression)expression ).Body );
                      case ExpressionType.Convert:
                          return GetValue( ( (UnaryExpression)expression ).Operand );
                      case ExpressionType.Equal:
                      case ExpressionType.NotEqual:
                      case ExpressionType.GreaterThan:
                      case ExpressionType.LessThan:
                      case ExpressionType.GreaterThanOrEqual:
                      case ExpressionType.LessThanOrEqual:
                          return GetValue( ( (BinaryExpression)expression ).Right );
                      case ExpressionType.Call:
                          return GetValue( ( (MethodCallExpression)expression ).Arguments.FirstOrDefault() );
                      case ExpressionType.MemberAccess:
                          return GetMemberValue( (MemberExpression)expression );
                      case ExpressionType.Constant:
                          return GetConstantExpressionValue( expression );
                  }
                  return null;
              }
      
              /// <summary>
              /// 獲取屬性表達(dá)式的值
              /// </summary>
              private static object GetMemberValue( MemberExpression expression ) {
                  if ( expression == null )
                      return null;
                  var field = expression.Member as FieldInfo;
                  if ( field != null ) {
                      var constValue = GetConstantExpressionValue( expression.Expression );
                      return field.GetValue( constValue );
                  }
                  var property = expression.Member as PropertyInfo;
                  if ( property == null )
                      return null;
                  var value = GetMemberValue( expression.Expression as MemberExpression );
                  return property.GetValue( value );
              }
      
              /// <summary>
              /// 獲取常量表達(dá)式的值
              /// </summary>
              private static object GetConstantExpressionValue( Expression expression ) {
                  var constantExpression = (ConstantExpression)expression;
                  return constantExpression.Value;
              }

        運行了全部測試,全部通過,說明沒有影響之前的功能。這正是自動化回歸測試的威力,如果沒有單元測試,我哪里敢重構(gòu)這些代碼呢。另外,修改Bug采用TDD的方式,能夠一次修復(fù),永絕后患,值得你擁有。

        同時,我還重構(gòu)了其它類似的代碼,就不再貼出,下次我發(fā)放源碼時,有興趣可以看看。

         .Net應(yīng)用程序框架交流QQ群: 386092459,歡迎有興趣的朋友加入討論。

        謝謝大家的持續(xù)關(guān)注,我的博客地址:http://www.rzrgm.cn/xiadao521/

      posted @ 2015-01-24 02:22  何鎮(zhèn)汐  閱讀(3759)  評論(6)    收藏  舉報
      主站蜘蛛池模板: 亚洲一区二区av偷偷| 武夷山市| 国产真实younv在线| 色婷婷日日躁夜夜躁| 国产精品自在自线视频| 最新国产精品拍自在线观看| 亚洲永久精品日本久精品| 亚洲日本韩国欧美云霸高清| 天堂网亚洲综合在线| 亚洲精品国产一区二区三| 91人妻熟妇在线视频| 国产精品国产三级国产专| 色欲国产精品一区成人精品| 香蕉av777xxx色综合一区| 亚洲gv天堂无码男同在线观看| 中文字幕国产精品av| 久久国产欧美日韩精品图片| 亚洲精品日韩久久精品| 免费av深夜在线观看| 欧洲精品码一区二区三区| 精品无码久久久久国产动漫3d| 18禁无遮挡啪啪无码网站破解版 | 一区二区三区精品偷拍| 国产精品无码一区二区在线 | 日韩精品一区二区都可以| 精品国产日韩亚洲一区| 丰满妇女强制高潮18xxxx| 在线观看国产区亚洲一区| 亚洲精品中文av在线| 日本国产精品第一页久久| 亚洲精品久综合蜜| 久久香蕉国产线看观看猫咪av| 国产欧美精品区一区二区三区| 免费国产精品黄色一区二区| 樱花草视频www日本韩国| 欧美极品色午夜在线视频| 亚洲综合黄色的在线观看| 成人国产精品免费网站| 精品国产成人网站一区在线| 睢宁县| 天堂V亚洲国产V第一次|