diff --git a/README.md b/README.md index fd53ab9d746034993b1383d009df48274308f454..e023be690c6b93123c603601d838800d58dfecf0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - **从 3.0 后分离了各个功能包,极力避免`DotNetCommon.Core`对其他包的依赖;** -- **从 4.0 后使用`SharpCompress`替代`SharpZipLib`**封装解压缩功能; +- **从 4.0 后使用`SharpCompress`替代`SharpZipLib` 封装解压缩功能;** **整体关系如下图:** diff --git a/docs/README.md b/docs/README.md index badb3403367233baff9737cdc9b39834ec5556bb..72892565cdbb7379c15d5c0a511569bd1fc5cfed 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,7 +18,7 @@ - **从 3.0 后分离了各个功能包,极力避免`DotNetCommon.Core`对其他包的依赖;** -- **从 4.0 后使用`SharpCompress`替代`SharpZipLib`**封装解压缩功能; +- **从 4.0 后使用`SharpCompress`替代`SharpZipLib`封装解压缩功能;** **整体关系如下图:** diff --git a/src/DotNetCommon.Core/DotNetCommon.Core.csproj b/src/DotNetCommon.Core/DotNetCommon.Core.csproj index 4f3cc28cfb283776b0efc5a70e597cdc19699803..b9cbfc333266dd36bac2386dfe860e094b721aa6 100644 --- a/src/DotNetCommon.Core/DotNetCommon.Core.csproj +++ b/src/DotNetCommon.Core/DotNetCommon.Core.csproj @@ -1,7 +1,7 @@ - 3.1.2 + 3.1.3 True .net常用功能及数据模型,包含: diff --git a/src/DotNetCommon.Core/ExpressionHelper.cs b/src/DotNetCommon.Core/ExpressionHelper.cs index 369debd067650beb9fcf441e5a9c01533a909858..e3f9f9f5adf433ee70331603d84b392234b7735a 100644 --- a/src/DotNetCommon.Core/ExpressionHelper.cs +++ b/src/DotNetCommon.Core/ExpressionHelper.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Xml.Linq; namespace DotNetCommon { @@ -179,7 +180,7 @@ namespace DotNetCommon var root = new ExpressionNode { Expression = lambdaExpression, - _parameters = lambdaExpression.Parameters.ToList(), + _parameters = new List(), Children = new List() }; VisitTree(root); @@ -196,7 +197,7 @@ namespace DotNetCommon void VisitTree(ExpressionNode node) { if (node.Expression == null) return; - var visit = _caches[node.NodeType]; + var visit = GetVisit(node.NodeType); visit.Reduce(node, VisitTree); } } @@ -290,5 +291,11 @@ namespace DotNetCommon { ExpressionType.IsFalse, new IsFalseVisit() }, #endregion }; + + internal static BaseVisit GetVisit(ExpressionType expressionType) + { + var visit = _caches[expressionType]; + return visit; + } } } diff --git a/src/DotNetCommon.Core/Expressions/Base/BaseVisit.cs b/src/DotNetCommon.Core/Expressions/Base/BaseVisit.cs index 66bec3b750200b167380274d6e168074e1e42b5a..d6c513138246fe108d162ca40e1215edc9f40a21 100644 --- a/src/DotNetCommon.Core/Expressions/Base/BaseVisit.cs +++ b/src/DotNetCommon.Core/Expressions/Base/BaseVisit.cs @@ -1,3 +1,4 @@ +using DotNetCommon.Expressions.Visit; using System; using System.Collections.Generic; using System.Linq.Expressions; @@ -78,7 +79,14 @@ namespace DotNetCommon.Expressions.Base var child = node.Children[i]; if (!child.HasParameter && child.Expression != null) { - if (child.NodeType != ExpressionType.Constant) + if (child.NodeType == ExpressionType.Lambda) + { + //lambda表达式节点不能再进一步简化,最多将它的body简化成常量 + //因为有的方法本身接受的就是lambda表达式 + node.Children[i]._updateRequest = true; + //node.Children[i].FullMarkString = GenerateFullMarkString(node.Children[i]); + } + else if (child.NodeType != ExpressionType.Constant) { //进行简化 var res = child.Reduce(); @@ -87,8 +95,9 @@ namespace DotNetCommon.Expressions.Base { Parent = node, Expression = contant, - _updateRequest = true + _updateRequest = true, }; + node.Children[i].FullMarkString = ConstantVisit.StaticGenerateFullMarkString(node.Children[i]); } } } @@ -97,6 +106,7 @@ namespace DotNetCommon.Expressions.Base if (node.NeedUpdate) { node.Expression = Rebuild(node); + node.FullMarkString = ExpressionHelper.GetVisit(node.NodeType).GenerateFullMarkString(node); } } diff --git a/src/DotNetCommon.Core/Expressions/Visit/VisitImplements.cs b/src/DotNetCommon.Core/Expressions/Visit/VisitImplements.cs index 431ec87d93b77ed5376d797db2c6128f8144f0e1..6bddd5fb799b1a7536b86099a9dbfbcf7c4242b8 100644 --- a/src/DotNetCommon.Core/Expressions/Visit/VisitImplements.cs +++ b/src/DotNetCommon.Core/Expressions/Visit/VisitImplements.cs @@ -101,6 +101,7 @@ namespace DotNetCommon.Expressions.Visit node._updateRequest = true; node.Children.Clear(); node.IsParameter = false; + node.FullMarkString = ConstantVisit.StaticGenerateFullMarkString(node); } } } @@ -139,6 +140,7 @@ namespace DotNetCommon.Expressions.Visit node._updateRequest = true; node.Children.Clear(); node.IsParameter = false; + node.FullMarkString = ConstantVisit.StaticGenerateFullMarkString(node); } } } @@ -414,16 +416,18 @@ namespace DotNetCommon.Expressions.Visit var left = node.Children[1]; node.Expression = left.Expression; node._updateRequest = true; + node.IsParameter = node.Children[1].IsParameter; + node.FullMarkString = node.Children[1].FullMarkString; node.Children.Clear(); - node.IsParameter = false; } else { - var right = node.Children[1]; + var right = node.Children[2]; node.Expression = right.Expression; node._updateRequest = true; + node.IsParameter = node.Children[2].IsParameter; + node.FullMarkString = node.Children[2].FullMarkString; node.Children.Clear(); - node.IsParameter = false; } } } @@ -444,6 +448,11 @@ namespace DotNetCommon.Expressions.Visit } protected override string GenerateFullMarkString(ExpressionNode node) + { + return StaticGenerateFullMarkString(node); + } + + internal static string StaticGenerateFullMarkString(ExpressionNode node) { var contant = node.Expression as ConstantExpression; if (node.IsLocalVariable) @@ -551,6 +560,7 @@ namespace DotNetCommon.Expressions.Visit protected override void Prepare(ExpressionNode node) { var lambdaExpression = node.Expression as LambdaExpression; + node.Parameters.Add(lambdaExpression.Parameters); node.Children.Add(new ExpressionNode { Parent = node, diff --git a/tests/DotNetCommon.Test/ExpressionHelperTests/ReduceLambdaTests.cs b/tests/DotNetCommon.Test/ExpressionHelperTests/ReduceLambdaTests.cs index cbbed0fdb3b51aa13d2f0f977562839553a238aa..99e208a3d529a0de2e0684f2b6e6785a9ebe288d 100644 --- a/tests/DotNetCommon.Test/ExpressionHelperTests/ReduceLambdaTests.cs +++ b/tests/DotNetCommon.Test/ExpressionHelperTests/ReduceLambdaTests.cs @@ -401,6 +401,32 @@ namespace DotNetCommon.Test.ExpressionHelperTests } #endregion + + #region + class Person2 + { + public int Id { get; set; } + public int Age { get; set; } + } + [Test] + public void NestedLambdaTest() + { + //内嵌lambda表达式 + var flag = 1 > 0; + Expression, bool>> lambda2 = (IEnumerable i) => i.Count() > 0 && i.Where(p => p.Id > 100 && flag).Any(); + var ret2 = ExpressionHelper.ReduceLambda(lambda2); + ret2.ToString().ShouldBe("i => ((i.Count() > 0) AndAlso i.Where(p => ((p.Id > 100) AndAlso True)).Any())"); + + Expression, object>> lambda = (IEnumerable i) => i.Where(p => p.Id > 100 || flag); + var ret = ExpressionHelper.ReduceLambda(lambda); + ret.ToString().ShouldBe("i => i.Where(p => True)"); + var del = (ret as LambdaExpression).Compile(); + var res = del.DynamicInvoke(new[] { new List { new Person2() { Id = 2, Age = 18 } } }) as IEnumerable; + res.Count().ShouldBe(1); + res.FirstOrDefault().Id.ShouldBe(2); + res.FirstOrDefault().Age.ShouldBe(18); + } + #endregion } #endregion