如何在C#
中获取Func<>
Lambda的传递参数的值
IEnumerable<AccountSummary> _data = await accountRepo.GetAsync();
string _query = "1011";
Accounts = _data.Filter(p => p.AccountNumber == _query);
这是我的扩展方法
public static ObservableCollection<T> Filter<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
string _target = predicate.Target.ToString();
// i want to get the value of query here.. , i expect "1011"
throw new NotImplementedException();
}
我想在分配给 _target 的过滤器扩展方法中获取查询的值
答案 0 :(得分:11)
如果要获取参数,则必须传递表达式。通过传递“Func”,您将传递已编译的lambda,因此您无法再访问表达式树。
public static class FilterStatic
{
// passing expression, accessing value
public static IEnumerable<T> Filter<T>(this IEnumerable<T> collection, Expression<Func<T, bool>> predicate)
{
var binExpr = predicate.Body as BinaryExpression;
var value = binExpr.Right;
var func = predicate.Compile();
return collection.Where(func);
}
// passing Func
public static IEnumerable<T> Filter2<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
return collection.Where(predicate);
}
}
TestMethod的
var accountList = new List<Account>
{
new Account { Name = "Acc1" },
new Account { Name = "Acc2" },
new Account { Name = "Acc3" },
};
var result = accountList.Filter(p => p.Name == "Acc2"); // passing expression
var result2 = accountList.Filter2(p => p.Name == "Acc2"); // passing function
答案 1 :(得分:1)
所以不要将谓词作为Func<T,bool>
传递给表达式树而不是Expression<Func<T,bool>
然后你可以检查它是什么类型的表达式并获得它的组成部分,它不会影响方法的调用方式,你仍然可以传递一个lambda。
答案 2 :(得分:0)
我真的不认为你能做到这一点。检查以下情况:
您的predicate
设置为Func<T, bool> predicate
,因此您可以这样称呼它:
Accounts = _data.Filter(p => true);
您希望通过这种电话获得什么?
(p) => true
满足Func<T, bool>
,因为它需要T
作为输入并返回bool
值。
答案 3 :(得分:0)
我受到了 Fried 的回答的启发,并找到了另一种方法来解决这个问题:
将 Func
将 Expression.Right 转换为 Lambda 函数 Func,它将返回表达式的 RHS 值。
public static void Filter<T>(this IEnumerable<T> collection, Expression<Func<T, bool>> predicate)
{
int value = Expression.Lambda<Func<int>>(predicate.Right).Compile().Invoke();
}