迭代 && 或 || 之间的每个参数在一个表达式> lambda 表达式中
本文关键字:表达式 amp 一个 lambda func bool 之间 参数 迭代 | 更新日期: 2023-09-27 18:32:44
我想要一个类似于遵循 LINQ-to-SQL Where
方法的方法。
db.Where(r => r.Age == 42 && r.Name = "Joe");
我想实现:
Something something = Get<Something>()
.FilterBy(x => x.PropOne == 123 && x.PropTwo == 456);
并使用如下所示的方法;能够访问每个表达式参数的 Left.Name、运算符和 Right.Value 以执行工作。
public static T FilterBy<T>(this T something, Expression<Func<T, object>> e)
{
// do work here
}
到目前为止,我可以使用以下方法解析像 x => x.PropOne == 123
这样的单个条件,而无需使用 &&&或 || 。
public static T FilterBy<T>(this T something, Expression<Func<T, object>> e)
{
BinaryExpression binaryExpression =
(BinaryExpression)((UnaryExpression)e.Body).Operand;
string left = ((MemberExpression)binaryExpression.Left).Member.Name;
string right = binaryExpression
.Right.GetType().GetProperty("Value")
.GetValue(binaryExpression.Right).ToString();
ExpressionType @operator = binaryExpression.NodeType;
return (T)Convert.ChangeType(something, typeof(T));
}
当表达式部分与&&
或||
组合时,如何访问每个表达式参数?
示例代码
下面是如何获取&&
的示例:
public static class FilterExtension
{
public class Condition
{
public string Name { get; set; }
public string Value { get; set; }
public string Operator { get; set; }
}
public static T FilterBy<T>(this T something, Expression<Func<T, object>> e)
{
var conditions = new List<Condition>();
BinaryExpression binaryExpression =
(BinaryExpression)((UnaryExpression)e.Body).Operand;
CheckConditions(conditions, binaryExpression);
return (T)Convert.ChangeType(test, typeof(T));
}
private static void CheckConditions(List<Condition> conditions, BinaryExpression binaryExpression)
{
if (binaryExpression.NodeType == ExpressionType.AndAlso)
{
CheckConditions(conditions, binaryExpression.Left as BinaryExpression);
CheckConditions(conditions, binaryExpression.Right as BinaryExpression);
}
else
{
conditions.Add(GetCondition(binaryExpression));
}
}
private static Condition GetCondition(BinaryExpression binaryExpression)
{
var condition = new Condition();
condition.Name = ((MemberExpression)binaryExpression.Left).Member.Name;
condition.Value = binaryExpression
.Right.GetType().GetProperty("Value")
.GetValue(binaryExpression.Right, null).ToString();
condition.Operator = binaryExpression.NodeType.ToString();
return condition;
}
}
显然,&&
的代码并不完整;你应该得到一个想法。
另外,我注意到您传入了一个类型为 T
的对象。如果这像 Linq-To-SQL 一样工作,它可能应该是某种列表或可枚举的。
例: public static T FilterBy<T>(this List<T> something, Expression<Func<T, object>> e)
考虑
请注意,可以将许多不同的表达式传递到此方法中,这些表达式将编译但会破坏您的方法。
Something something = Get<Something>().FilterBy(x => 123 == x.PropOne);
Something something = Get<Something>().FilterBy(x => x.Method() == 123);
Something something = Get<Something>().FilterBy(x => (x.PropOne == 123 || x.PropOne == 34) && x.PropTwo == 456 );
请确保验证表达式是否为预期类型。