C# 直接使用Linq表达式变量而不是lambda表达式时出错
我使用以下代码从类型为类的程序集获取类型集合:C# 直接使用Linq表达式变量而不是lambda表达式时出错,c#,linq,generics,C#,Linq,Generics,我使用以下代码从类型为类的程序集获取类型集合: Assembly assembly = Assembly.LoadFile(DLLFile); var types = assembly.GetTypes().AsEnumerable().Where(x => x.IsClass); 这很好,正如预期的那样。但是,我想将lambda表达式提取到一个Linq表达式变量中(稍后将在该方法的参数中使用它)。因此,我做了以下工作: private Expression<Func<Typ
Assembly assembly = Assembly.LoadFile(DLLFile);
var types = assembly.GetTypes().AsEnumerable().Where(x => x.IsClass);
这很好,正如预期的那样。但是,我想将lambda表达式提取到一个Linq表达式变量中(稍后将在该方法的参数中使用它)。因此,我做了以下工作:
private Expression<Func<Type, bool>> _standardFilter = (x => x.IsClass);
Assembly assembly = Assembly.LoadFile(DLLFile);
var types = assembly.GetTypes().AsEnumerable().Where(_standardFilter);
private Expression\u standardFilter=(x=>x.IsClass);
Assembly=Assembly.LoadFile(DLLFile);
var types=assembly.GetTypes().AsEnumerable().Where(\u standardFilter);
但是,这不会编译为错误:
System.Collections.Generic.IEnumerable<System.Type>' does not contain a
definition for 'Where' and the best extension method overload
'System.Linq.Enumerable.Where<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,int,bool>)' has some invalid arguments
System.Collections.Generic.IEnumerable'不包含
“Where”和最佳扩展方法重载的定义
“System.Linq.Enumerable.Where(System.Collections.Generic.IEnumerable,System.Func)”具有一些无效参数
我知道我的表达式不符合谓词System.Func
,但是Where
函数有一个重载,该重载接受System.Func
的谓词,据我所知,它应该可以工作
我已经尝试过将assembly.GetTypes()
(一个数组)的结果以多种方式转换为列表,但没有帮助解决这个问题
我还确保使用该类的语句获得了所有正确的,因为这似乎是我在谷歌搜索时遇到的一个问题
过去,我曾在IQueryable
集合上使用过相同的技术,但我不明白当Where
函数在IEnumerable
集合上可用并且应该接受我提供的谓词时,为什么这样做行不通
非常感谢您的帮助。将表达式编译为可执行代码(委托):
正如@Kirk所说,如果不打算分析表达式树,最好不要使用表达式树。只需使用Func
类型的过滤器,您可以尝试以下方法:
private Func<Type, bool> standardFilter;
standardFilter = (type) => {
return type.IsClass;
};
var types = assembly.GetTypes().AsEnumerable().Any(x => standardFilter(x));
private Func标准过滤器;
标准过滤器=(类型)=>{
返回类型.IsClass;
};
var types=assembly.GetTypes().AsEnumerable().Any(x=>standardFilter(x));
然后您可以自由更改standardFilter的实现。只要它接受一个类型并返回bool以确定是否应该包含它,它就会保持模块化,并实现我认为您要实现的目标。请注意,可枚举扩展方法采用的是Func,而不是表达式。所以你的论点打错了
这与实体框架不同,实体框架采用表达式而不是普通函数
所以要注意方法签名,它们是相似的,都可以用相同的lambda调用,但实际上是不同的
这背后的原因是EF检查表达式并将其转换为SQL代码,而Linq to Object只是在内存中执行谓词。甚至更好,首先不要将lambda包装在表达式树中。@KirkWoll完全同意你的观点:)expression
和Func
不是一回事。IQueryable
上的Where
扩展方法接受一个表达式,这就是为什么你以前能够这样做的原因。这就是允许EF之类的东西传入表达式并在以后编译它的原因。但是在IEnumerable
上,它只接受
。因此,它再次归结为我没有注意到一个特定的单词!我真的应该时不时地退一步,多注意我所设想的事情!或者只需私有Func standardFilter=type=>type.IsClass;变量类型=assembly.GetTypes().AsEnumerable().Any(standardFilter);
private Func<Type, bool> standardFilter;
standardFilter = (type) => {
return type.IsClass;
};
var types = assembly.GetTypes().AsEnumerable().Any(x => standardFilter(x));