我编写了下面的代码来计算布尔表达式。表达式以对象的形式编码。
当我查看代码并思考时,这是其中一个时刻:我确信有一种更好的编码方法,使用更少的布尔变量,但看不到正确的方法。有什么帮助吗?单元测试已经编写完毕,并且正在通过各种输入。
if (tree == null || !tree.IsActive || tree.FilterNodes == null)
{
return false;
}
var result = false;
foreach (var filter in tree.FilterNodes.Where(a => a.IsActive && a.ConditionNodes != null))
{
var tempBool = false;
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
if (filter.LogicalOperator == LogicalOperator.Or && ApplyCondition(condition.ConditionOperator, value, condition.FieldValue))
{
tempBool = true;
break;
}
else if (filter.LogicalOperator == LogicalOperator.And)
{
tempBool = ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if (!tempBool)
{
break;
}
}
else
{
tempBool = false;
}
}
else if (!string.IsNullOrWhiteSpace(condition.FieldName) && filter.LogicalOperator == LogicalOperator.And)
{
tempBool = false;
}
}
result = tempBool;
if (!result)
{
break;
}
}
return result;
您可以在循环中设置tempBool = false
第一件事,省略else
和最后一个else if
:
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
tempBool = false;
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
if (filter.LogicalOperator == LogicalOperator.Or && ApplyCondition(condition.ConditionOperator, value, condition.FieldValue))
{
tempBool = true;
break;
}
else if (filter.LogicalOperator == LogicalOperator.And)
{
tempBool = ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if (!tempBool)
{
break;
}
}
}
}
编辑
它变得更加简单:
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
tempBool = false;
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
tempBool == ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if ((filter.LogicalOperator == LogicalOperator.And && !tempBool) || (filter.LogicalOperator == LogicalOperator.Or && tempBool))
{
break;
}
}
}
在 如果需要ApplyCondition
为 true,然后将tempBool
设置为true
(也是ApplyCondition
的结果(。在 else 中,如果您将tempBool
设置为ApplyCondition
的结果。这意味着您可以首先tempBool
设置为ApplyCondition
的结果。现在你只需要决定是否需要打破。
采用更 o-o 的方法,我认为您的运算符需要由从基类继承的类定义。基类将具有运算符实现的抽象 Evaluate 方法。然后,您可以使用 o-o 多态性来评估运算符,而无需担心内部细节。实际上,您已经有了一个简单的解释器的开始。
编写布尔解释器的一种更正式的方法是将布尔表达式视为由形式语法生成,并为其编写解析器和解释器。解释器可以作为抽象语法树实现。
我做了一个开源库来实现这一点,如果你愿意,你可以在GitHub上看看。