.net C# -将InvocationExpression转换为BinaryExpression以计算lambda的左侧/右侧

q43xntqr  于 2023-02-10  发布在  .NET
关注(0)|答案(1)|浏览(73)

我需要得到Lambda的左/右手边
ie for(x =〉x.Foo〈x.Bar)我想同时计算x.Foo和x. Bar。lambda表达式都保证是二进制的

using System.Linq.Expressions;

var ExampleCheck = new FooChecker<M>(x => x.Foo < x.Bar);

var evalLeftHandSide = EvalLeftHandSide<M>(ExampleCheck.CheckToMake);

double EvalLeftHandSide<T>(Func<T, bool> CheckToMake)
{
    Expression<Func<T, bool>> CheckAsExpression = (x) => CheckToMake(x);

    //use the incoming expression
    BinaryExpression be = CheckAsExpression.Body as BinaryExpression; <<<always null

    Expression LHS;
    if (be == null)
        return 0;
    LHS = be.Left;
    // provide parameters of incoming expression to lambda
    var LHSCompiled = Expression.Lambda(LHS, CheckAsExpression.Parameters).Compile();
    // provide the incoming parameter to the invocation 
    var LHSValue = LHSCompiled.DynamicInvoke(Activator.CreateInstance<T>());

    return Convert.ToDouble(LHSValue);
}

struct FooChecker<T>
{
    public FooChecker(Func<T, bool> _CheckToMake) { CheckToMake = _CheckToMake; }

    public Func<T, bool> CheckToMake;
}

class M
{
    public double Foo { get; set; }
    public double Bar { get; set; }
}

我无法将表达式转换为BinaryExpression,因为它实际上是一个InvocationExpression...是否可以从InvocationExpression〉BinaryExpression中获取,或者单独计算InvocationExpression左侧/右侧的方法?
干杯

yyyllmsg

yyyllmsg1#

假设您传递的是x => x.Foo < x.Bar表达式,您要执行的操作的第一近似值可能如下所示:

// usage
var evalLeftHandSide = EvalLeftHandSide<M>(x => x.Foo < x.Bar);

double EvalLeftHandSide<T>(Expression<Func<T, bool>> CheckToMake)
{
    //use the incoming expression
    BinaryExpression be = CheckToMake.Body as BinaryExpression;

    if (be == null)
        return 0;

    Expression LHS = be.Left; 
    // provide parameters of incoming expression to lambda
    var LHSCompiled = Expression.Lambda(LHS, CheckToMake.Parameters).Compile();
    // provide the incoming parameter to the invocation 
    var LHSValue = LHSCompiled.DynamicInvoke(Activator.CreateInstance<T>());

    return Convert.ToDouble(LHSValue);
}

class M
{
    public int Foo { get; set; }
    public int Bar { get; set; }
}

注解表示对原始代码的更改。
注意,这还远远不够完美--它做了很多假设(比如类型有无参数的ctor,考虑new()泛型约束或以其他方式提供T,或者左侧表达式结果可转换为double)。

相关问题