c# - 如何获得影响其输出的表达式树的所有因素

标签 c# .net expression-trees

给定一个类型为 Expression<Func<int>> 的任意表达式,我怎样才能得到可能但不一定会影响结果的所有对象的列表。

我正在寻找这样的函数:

IEnumerable<object> GetFactors(Expression<Func<int>> expression)
{
    //return a list of all objects in the expression that affect the result.
}

示例 1

Expression<Func<int>> expression = () => a + b;

哪里abint小号,GetFactors会返回 IEnumerable<object>包含 ab .

示例 2

Expression<Func<int>> expression = () => obj1 != obj2 ? a + b : c + d;

GetFactors会返回 IEnumerable<object>包含 obj1 , obj2 , a , b , c , 和 d .

最佳答案

您需要像这样实现自定义表达式访问者类:

public class FactorVisitor : ExpressionVisitor
{
    List<object> factors = new List<object>();

    private FactorVisitor(Expression<Func<int>> expression)
    {
        Visit(expression);
    }

    public static List<object> GetFactors(Expression<Func<int>> expression)
    {
        return new FactorVisitor(expression).factors;
    }

    // Add this method for listing compile-time constant values
    protected override Expression VisitConstant(ConstantExpression node)
    {
        factors.Add(node.Value);
        return node;
    }

    protected override Expression VisitMember(MemberExpression node)
    {
        if (CanBeEvaluated(node))
        {
            factors.Add(Evaluate(node));
        }
        return node;
    }

    private static bool CanBeEvaluated(MemberExpression exp)
    {
        while (exp.Expression.NodeType == ExpressionType.MemberAccess)
        {
            exp = (MemberExpression) exp.Expression;
        }

        return (exp.Expression.NodeType == ExpressionType.Constant);
    }

    private static object Evaluate(Expression exp)
    {
        if (exp.NodeType == ExpressionType.Constant)
        {
            return ((ConstantExpression) exp).Value;
        }
        else
        {
            MemberExpression mexp = (MemberExpression) exp;
            object value = Evaluate(mexp.Expression);

            FieldInfo field = mexp.Member as FieldInfo;
            if (field != null)
            {
                return field.GetValue(value);
            }
            else
            {
                PropertyInfo property = (PropertyInfo) mexp.Member;
                return property.GetValue(value, null);
            }
        }
    }
}

请注意,您只会获得变量的值,即使对于像 a.b 这样的成员调用也是如此。

关于c# - 如何获得影响其输出的表达式树的所有因素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10393560/

相关文章:

c# - NUnit:如何从非静态方法传递 TestCaseData?

c# - 您可以在 XAML 中引用其他属性中的属性吗?

.net - 通用ILogger,或者通过Serilog,添加logging属性

c# - 将对象的哈希码定义为所有类变量哈希码的总和、乘法等等是不正确的吗?

C# 正则表达式和 html,以第一个 "结尾

c# - 从 lambda 创建表达式树

c# - 如何在 .NET 中获取 "basic"中的 "container type"类型?

c# - 如何根据内部 json 对象值在 DocumentDB 中查询?

C# EF Core 使用表达式树构建动态选择语句

entity-framework - 如何包含检查属性及其值的 And() 表达式