给定一个类型为 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;
哪里a
和 b
是 int
小号,GetFactors
会返回 IEnumerable<object>
包含 a
和 b
.
示例 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/