C# 确定动态LINQ表达式中的条件数
我选择将名称空间实现到我的项目中,我依赖于根据底层对象从字符串动态调用LINQ表达式。这允许在数据级别实现高度可配置的标准C# 确定动态LINQ表达式中的条件数,c#,linq,C#,Linq,我选择将名称空间实现到我的项目中,我依赖于根据底层对象从字符串动态调用LINQ表达式。这允许在数据级别实现高度可配置的标准 string expression = "x.Client == 100 && x.Insurers.Any(it == 2 || it == 3)"; var x = new MyObject() { Client = 100, Insurers = new int[] { 1, 2 }}; var p = Expression.Parameter(
string expression = "x.Client == 100 && x.Insurers.Any(it == 2 || it == 3)";
var x = new MyObject() { Client = 100, Insurers = new int[] { 1, 2 }};
var p = Expression.Parameter(typeof(MyObject), "x");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, expression);
bool result = e.Compile().DynamicInvoke(x); // True = condition met
我的问题是如何动态识别每个字符串表达式包含的条件数量,以便在发生重叠时为每个表达式赋予权重,并选择权重最高的表达式<代码>正则表达式可以工作,但必须有更有效和实用的方法,例如表达式树
例:
我不熟悉
System.Linq.Dynamic
库,但假设它生成正常的强类型表达式
树,您可以使用
这一项统计布尔逻辑运算的数量,如&&
:
int CountConditions(Expression expr)
{
var visitor = new CountBinaryOpsVisitor();
visitor.Visit(expr);
return visitor.BinaryOperationCount + 1;
}
class CountBinaryOpsVisitor : ExpressionVisitor
{
public int BinaryOperationCount { get; private set; }
protected override Expression VisitBinary(BinaryExpression node)
{
switch (node.NodeType)
{
case ExpressionType.And:
case ExpressionType.AndAlso:
case ExpressionType.Or:
case ExpressionType.OrElse:
case ExpressionType.ExclusiveOr:
// Don't count bitwise integer operations, if they are even supported?
if (node.Left.Type == typeof(bool))
BinaryOperationCount++;
break;
}
return base.VisitBinary(node);
}
}
另一种方法是计算比较运算符的数量(=
,=
等),但我认为需要更复杂的代码来处理布尔表达式,如x.BooleanProp
或x.Any()
此实现当前不计算条件表达式(
x?y:z
)。不确定如何将这些因素考虑到条件数中,尤其是嵌套时。计算比较运算符应与计算逻辑运算符一样容易,只是一组不同的ExpressionType
s.@NetMage我所指的复杂性是像x=>x.BooleanProperty
这样的布尔表达式不会生成任何特定的比较或真实性表达式,它只是MemberAccess
或调用
,因此,您需要将布尔值与其他成员访问(如x.Foo.Bar.IntegerProperty
)区分开来,然后确保不将x.BooleanExpression==true
计数两次。@kalimag这样的回答让我意识到我还有多少关于C的知识需要学习。谢谢
int CountConditions(Expression expr)
{
var visitor = new CountBinaryOpsVisitor();
visitor.Visit(expr);
return visitor.BinaryOperationCount + 1;
}
class CountBinaryOpsVisitor : ExpressionVisitor
{
public int BinaryOperationCount { get; private set; }
protected override Expression VisitBinary(BinaryExpression node)
{
switch (node.NodeType)
{
case ExpressionType.And:
case ExpressionType.AndAlso:
case ExpressionType.Or:
case ExpressionType.OrElse:
case ExpressionType.ExclusiveOr:
// Don't count bitwise integer operations, if they are even supported?
if (node.Left.Type == typeof(bool))
BinaryOperationCount++;
break;
}
return base.VisitBinary(node);
}
}