Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 直接使用Linq表达式变量而不是lambda表达式时出错_C#_Linq_Generics - Fatal编程技术网

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));