質問で提起された要件に対処するための再利用可能な.NETFrameworkコンポーネントはないようです。ただし、Andrey Shchekinの ツールリファレンスは、必要なコンポーネントの作成方法に関する優れたリファレンスを提供しました。
これは、順次Not()演算子のキャンセル、Not()演算子のバイナリ式への分散、およびド・モルガンの法則の適用に対処するスニペットです。
public class NotCollapser : ExpressionVisitor
{
// Incomplete list; others removed for brevity.
private static readonly IDictionary<ExpressionType, Func<BinaryExpression, BinaryExpression>> NotDistributionMap =
{
{ ExpressionType.Equal, e => Expression.MakeBinary(ExpressionType.NotEqual, e.Left, e.Right) },
{ ExpressionType.NotEqual, e => Expression.MakeBinary(ExpressionType.Equal, e.Left, e.Right) },
{ ExpressionType.GreaterThan, e => Expression.MakeBinary(ExpressionType.LessThanOrEqual, e.Left, e.Right) },
{ ExpressionType.AndAlso, e => Expression.MakeBinary(ExpressionType.OrElse, Expression.Not(e.Left), Expression.Not(e.Right)) },
{ ExpressionType.OrElse, e => Expression.MakeBinary(ExpressionType.AndAlso, Expression.Not(e.Left), Expression.Not(e.Right)) }
};
protected override Expression VisitUnary(UnaryExpression expression)
{
if (expression.NodeType == ExpressionType.Not)
{
if (expression.Operand.NodeType == ExpressionType.Not)
{
return Visit((expression.Operand as UnaryExpression).Operand);
}
if (NotDistributionMap.ContainsKey(expression.Operand.NodeType))
{
var distribute = NotDistributionMap[expression.Operand.NodeType];
return Visit(distribute(expression.Operand as BinaryExpression));
}
}
return base.VisitUnary(expression);
}
}