在 C# 中评估布尔表达式
Evaluating boolean expression in C#
我编写了下面的代码来评估布尔表达式。表达式以对象的形式编码。
这是我查看代码并思考的时刻之一:我确信有更好的编码方法,使用更少的布尔变量但看不到正确的方法。有什么帮助吗?已编写单元测试并通过各种输入。
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
为真然后将tempBool
设置为true
(也是ApplyCondition
的结果)。在 else 中,如果将 tempBool
设置为 ApplyCondition
的结果。这意味着您可以首先将 tempBool
设置为 ApplyCondition
的结果。现在你只需要决定是否需要休息。
采用更 o-o 的方法,我认为您的运算符需要由继承自基础 class 的 classes 定义。基础 class 将具有您的操作员实现的抽象 Evaluate 方法。然后,您可以使用 o-o 多态性来评估您的运算符,而无需担心内部细节。实际上,您已经开始使用简单的解释器了。
编写布尔解释器的一种更正式的方法是考虑由 正式语法 生成的布尔表达式并编写 解析器 和一个解释器。解释器可以实现为 抽象语法树 .
我做了一个开源库来实现这个,如果你想看一下GitHub。
我编写了下面的代码来评估布尔表达式。表达式以对象的形式编码。
这是我查看代码并思考的时刻之一:我确信有更好的编码方法,使用更少的布尔变量但看不到正确的方法。有什么帮助吗?已编写单元测试并通过各种输入。
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
为真然后将tempBool
设置为true
(也是ApplyCondition
的结果)。在 else 中,如果将 tempBool
设置为 ApplyCondition
的结果。这意味着您可以首先将 tempBool
设置为 ApplyCondition
的结果。现在你只需要决定是否需要休息。
采用更 o-o 的方法,我认为您的运算符需要由继承自基础 class 的 classes 定义。基础 class 将具有您的操作员实现的抽象 Evaluate 方法。然后,您可以使用 o-o 多态性来评估您的运算符,而无需担心内部细节。实际上,您已经开始使用简单的解释器了。
编写布尔解释器的一种更正式的方法是考虑由 正式语法 生成的布尔表达式并编写 解析器 和一个解释器。解释器可以实现为 抽象语法树 .
我做了一个开源库来实现这个,如果你想看一下GitHub。