c# – 需要和\u0026\u0026一起使用不确定数量的Func
我正试图找到一个好方法,累积应用最多5个Func到同一个IEnumerable.这是我想出的:
private Func<SurveyUserView,bool> _getFilterLambda(IDictionary<string,string> filters) { Func<SurveyUserView,bool> invokeList = delegate(SurveyUserView surveyUserView) { return surveyUserView.deleted != "deleted"; }; if (filters.ContainsKey("RegionFilter")) { invokeList += delegate(SurveyUserView surveyUserView) { return surveyUserView.Region == filters["RegionFilter"]; }; } if (filters.ContainsKey("LanguageFilter")) { invokeList += delegate(SurveyUserView surveyUserView) { return surveyUserView.Locale == filters["LanguageFilter"]; }; } if (filters.ContainsKey("StatusFilter")) { invokeList += delegate(SurveyUserView surveyUserView) { return surveyUserView.Status == filters["StatusFilter"]; }; } if (filters.ContainsKey("DepartmentFilter")) { invokeList += delegate(SurveyUserView surveyUserView) { return surveyUserView.department == filters["DepartmentFilter"]; }; } return invokeList; } 我认为它会以累积方式应用这些,但是,我可以从结果中看出它实际上只是应用了最后一个(DepartmentFilter). 有2 ^ 4种可能的组合,所以如果/ elses不起作用的话. (我希望仅在字典中存在相应的键时才使用特定的lambda.) 编辑: private Func<SurveyUserView,string> filters ) { Func<SurveyUserView,bool> resultFilter = (suv) => suv.deleted != "deleted"; if (filters.ContainsKey("RegionFilter")) { Func<SurveyUserView,bool> newFilter = (suv) => resultFilter(suv) && suv.Region == filters["RegionFilter"]; resultFilter = newFilter; } if (filters.ContainsKey("LanguageFilter")) { Func<SurveyUserView,bool> newFilter = (suv) => resultFilter(suv) && suv.Locale == filters["LanguageFilter"]; resultFilter = newFilter; } if (filters.ContainsKey("StatusFilter")) { Func<SurveyUserView,bool> newFilter = (suv) => resultFilter(suv) && suv.Status == filters["StatusFilter"]; resultFilter = newFilter; } if (filters.ContainsKey("DepartmentFilter")) { Func<SurveyUserView,bool> newFilter = (suv) => resultFilter(suv) && suv.department == filters["DepartmentFilter"]; resultFilter = newFilter; } return resultFilter; } 编辑: 理解为什么无限递归发生的重要一点是理解lambda中的符号何时被解析(即在运行时而不是在定义时). 举个简单的例子: Func<int,int> demo = (x) => x * 2; Func<int,int> demo2 = (y) => demo(y) + 1; demo = demo2; int count = demo(1); 如果它在定义时被静态解析,那么它将起作用并且与以下相同: Func<int,int> demo2 = (y) => (y * 2) + 1; Int count = demo2(1); 但它实际上并没有试图弄清楚demo2中嵌入的演示直到运行时 – 此时demo2已重新定义为演示.基本上代码现在是: Func<int,int> demo2 = (y) => demo2(y) + 1; Int count = demo2(1); 解决方法
您可以使用AND条件构建使用现有委托的新委托,而不是尝试以这种方式组合委托:
Func<SurveyUserView,bool> resultFilter = (suv) => true; if (filters.ContainsKey("RegionFilter")) { var tmpFilter = resultFilter; // Create a new Func based on the old + new condition resultFilter = (suv) => tmpFilter(suv) && suv.Region == filters["RegionFilter"]; } if (filters.ContainsKey("LanguageFilter")) { // Same as above... //... Continue,then: return resultFilter; 话虽这么说,传递你原来的IQueryable< SurveyUserView>可能更容易.或IEnumerable< SurveyUserView>进入这个方法,只需添加.Where子句直接过滤.然后,您可以返回最终查询而不执行它,并添加过滤器. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |