- 优化 导航集合属性访问,可省略 AsSelect;#15 #300 #362 #509 #698 #644 #903

This commit is contained in:
2881099
2022-04-27 20:27:24 +08:00
parent dcf7b9668f
commit f76a46f383
20 changed files with 1947 additions and 346 deletions

View File

@ -227,7 +227,7 @@ namespace System.Linq.Expressions
public static Expression<Func<T1, T2, T3, T4, T5, bool>> Not<T1, T2, T3, T4, T5>(this Expression<Func<T1, T2, T3, T4, T5, bool>> exp, bool condition = true) => (Expression<Func<T1, T2, T3, T4, T5, bool>>)InternalNotExpression(condition, exp);
#endregion
internal static bool IsParameter(this Expression exp)
public static bool IsParameter(this Expression exp)
{
var test = new TestParameterExpressionVisitor();
test.Visit(exp);
@ -258,6 +258,72 @@ namespace System.Linq.Expressions
toListArgs0Out = null;
return false;
}
public static object GetConstExprValue(this Expression exp)
{
if (exp.IsParameter()) return null;
var expStack = new Stack<Expression>();
var exp2 = exp;
while (true)
{
switch (exp2?.NodeType)
{
case ExpressionType.Constant:
expStack.Push(exp2);
break;
case ExpressionType.MemberAccess:
expStack.Push(exp2);
exp2 = (exp2 as MemberExpression).Expression;
if (exp2 == null) break;
continue;
case ExpressionType.Call:
return Expression.Lambda(exp).Compile().DynamicInvoke();
case ExpressionType.TypeAs:
case ExpressionType.Convert:
var oper2 = (exp2 as UnaryExpression).Operand;
if (oper2.NodeType == ExpressionType.Parameter)
{
var oper2Parm = oper2 as ParameterExpression;
expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name));
}
else
expStack.Push(oper2);
break;
}
break;
}
object firstValue = null;
switch (expStack.First().NodeType)
{
case ExpressionType.Constant:
var expStackFirst = expStack.Pop() as ConstantExpression;
firstValue = expStackFirst?.Value;
break;
case ExpressionType.MemberAccess:
var expStackFirstMem = expStack.First() as MemberExpression;
if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant)
firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value;
else
return Expression.Lambda(exp).Compile().DynamicInvoke();
break;
}
while (expStack.Any())
{
var expStackItem = expStack.Pop();
switch (expStackItem.NodeType)
{
case ExpressionType.MemberAccess:
var memExp = expStackItem as MemberExpression;
if (memExp.Member.MemberType == MemberTypes.Property)
firstValue = ((PropertyInfo)memExp.Member).GetValue(firstValue, null);
else if (memExp.Member.MemberType == MemberTypes.Field)
firstValue = ((FieldInfo)memExp.Member).GetValue(firstValue);
break;
}
}
return firstValue;
}
}
internal class NewExpressionVisitor : ExpressionVisitor