我正在关注这个 SO answer将 lambda 表达式转换为部分 SQL 语法。
但是,我在解析 Contains
的表达式时遇到问题。我添加了一个方法:
private bool ParseContainsExpression(MethodCallExpression expression)
{
MemberExpression member = (MemberExpression)expression.Arguments[0];
var methodInfo = typeof(List<int>).GetMethod("Contains", new Type[] { typeof(int) });
//TODO check if list contains value
return false;
}
由于我对表达式完全陌生,我不知道从哪里获取属性名称和值,以及包含我要检查的值的列表。这些属性和值存储在表达式中的什么位置?
最佳答案
您的实现与示例答案完全不同。您确实需要从 ExpressionVisitor
继承,以便您可以正确地解析树。
让我们以这个表达式为例:
var myList = new List<string> { "A" };
Expression<Func<string, bool>> a = (s) => myList.Contains(s);
ParseContainsExpression(a.Body as MethodCallExpression);
private bool ParseContainsExpression(MethodCallExpression expression)
{
expression.Object; //myList
expression.Arguments[0]; //s
return false;
}
但是请注意,这些仍然是表达式,它们还不是实际值。您需要调用表达式来获取值。
但是,在我们的例子中 - myList
实际上是一个 ConstantExpression
。所以我们可以这样做:
((expression.Object as MemberExpression).Expression as ConstantExpression).Value; //myList
返回原始列表。请注意,这是一个 field 访问,因为表达式被编译成一个闭包,它将 myList
作为闭包类中的一个字段。如您所见,我们必须对正在处理的表达式类型做出很多假设(它是一个字段访问,然后是一个常量表达式)。您确实需要一个成熟的访问者实现才能正确执行此操作(链接的答案描述了这一点)
关于c# - 如何为 Contains<T> 构建表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36713101/