首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将表达式x=>!x重写为x=>x!=true,将x=>x重写为x=>x==true

如何将表达式x=>!x重写为x=>x!=true,将x=>x重写为x=>x==true
EN

Stack Overflow用户
提问于 2014-01-27 13:30:17
回答 1查看 310关注 0票数 2

Asume,我们这样表达:

代码语言:javascript
复制
someIQueryable.Where(x => x.SomeBoolProperty)
someIQueryable.Where(x => !x.SomeBoolProperty)

我需要像上面这样的表达式(用表达式访问者重写)转换成这样的表达式:

代码语言:javascript
复制
someIQueryable.Where(x => x.SomeBoolProperty == true)
someIQueryable.Where(x => x.SomeBoolProperty != true)

注意:如果我们有更复杂的表达式,重写程序也必须在更一般的情况下工作:

代码语言:javascript
复制
 someIQueryable.Where((x => x.SomeBoolProperty && x.SomeIntProperty > 0) || !x.SomeOtherBoolProperty))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-27 13:39:59

类似于:

代码语言:javascript
复制
static class BooleanComplexifier
{
    public static Expression<T> Process<T>(Expression<T> expression)
        where T : class
    {
        var body = expression.Body;
        if (body.Type == typeof(bool))
        {
            switch(body.NodeType)
            {
                case ExpressionType.Equal:
                case ExpressionType.NotEqual:
                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:
                case ExpressionType.LessThan:
                case ExpressionType.LessThanOrEqual:
                    return expression;
                case ExpressionType.Not:
                    body = Expression.NotEqual(
                        ((UnaryExpression)body).Operand,
                        Expression.Constant(true));
                    break;
                default:
                        body = Expression.Equal(body,
                        Expression.Constant(true));
                    break;
            }
            return Expression.Lambda<T>(body, expression.Parameters);
        }
        return expression;
    }   
}

通过以下方式:

代码语言:javascript
复制
Expression<Func<Foo, bool>> x = foo => foo.IsAlive,
    y = foo => !foo.IsAlive;

var a = BooleanComplexifier.Process(x); // foo => foo.IsAlive == true
var b = BooleanComplexifier.Process(y); // foo => foo.IsAlive != true
//...
class Foo
{
    public bool IsAlive { get;set; }
}

对于更复杂的处理,可能需要一个ExpressionVisitor

代码语言:javascript
复制
class BooleanComplexifier : ExpressionVisitor
{
    public static Expression<T> Process<T>(Expression<T> expression)
    {
        return (Expression<T>)new BooleanComplexifier().Visit(expression);
    }

    int bypass;
    protected override Expression VisitBinary(BinaryExpression node)
    {
        if (bypass == 0 && node.Type == typeof(bool))
        {
            switch (node.NodeType)
            {
                case ExpressionType.And: // bitwise & - different to &&
                case ExpressionType.Or: // bitwise | - different to ||
                case ExpressionType.Equal:
                case ExpressionType.NotEqual:
                    bypass++;
                    var result = base.VisitBinary(node);
                    bypass--;
                    return result;
            }
        }
        return base.VisitBinary(node);
    }
    protected override Expression VisitUnary(UnaryExpression node)
    {
        if (bypass == 0 && node.Type == typeof(bool))
        {
            switch(node.NodeType)
            {
                case ExpressionType.Not:
                    bypass++;
                    var result = Expression.NotEqual(
                        base.Visit(node.Operand),
                        Expression.Constant(true));
                    bypass--;
                    return result;
            }
        }
        return base.VisitUnary(node);
    }
    protected override Expression VisitMember(MemberExpression node)
    {
        if(bypass == 0 && node.Type == typeof(bool))
        {
            return Expression.Equal(
                base.VisitMember(node),
                Expression.Constant(true));
        }
        return base.VisitMember(node);
    }
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21382175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档