我需要为列表中的每个项目调用方法。所以,我使用Where<>
查询如下,
List<string> list = new List<string>();
list.Add("Name1");
list.Add("Name2");
list.Add("Name3");
var name = list.Where(n =>
{
return CheckName(n);
});
但在上述情况下,CheckName()
未被击中。如果我使用FirstOrDefault<>
,则会触发相同的方法。我不知道这是一个框架中断还是我走错了路。
作为附加信息,我使用的是.NET Framework 4.5。
有没有人遇到过这个错误?如果是这样,有没有解决方案来解决这个问题?
答案 0 :(得分:3)
您错误地理解了Where
条件的结果。由于linq被执行了,它只会在实现时进入where条件(通过ToList
/ FirstOrDefault
/ Sum
等等。
Where
实际上从未在您当前的代码中实现(它与您使用FirstOrDefault
时所经历的那样),因此它永远不会进入CheckName
方法。然后,由于Where
永远不会返回null
,但“最坏情况”将是一个空集合,而不是null
,结果为true
。
如果您进行调试,则会在此结尾处看到name
等于true
。要“克服”这取决于你想要的输出:
如果您想知道您是否有任何与谓词匹配的项目:
var result = list.Any(CheckName);
如果要检索与谓词匹配的内容:
var result = list.Where(CheckName);
如果以后要查询并检查results
是否包含任何内容,请执行以下操作:
if(result.Any()) { /* ... */ }
如果您只想要结果(从而实现查询):
list.Where(CheckName).ToList();
在这里阅读更多关于linq被执行的信息:
正如旁注,了解如何更改当前代码:
var name = list.Where(n =>
{
return CheckName(n);
})
要:
var name = list.Where(n => CheckName(n));
最终:
var name = list.Where(CheckName);
答案 1 :(得分:2)
LINQ有延迟执行主体,这意味着除非您访问$(function() {
$('a.page-scroll').bind('click', function(event) {
$("html, body").animate({ scrollTop: 0 }, 1500);
event.preventDefault();
});
});
变量,否则不会执行查询。如果你想立即执行它,(仅举例)最后添加name
,这正是.ToList()
所做的。它立即执行而不是延迟执行。
FirstOrDefault
同样var name = list.Where(n =>
{
return CheckName(n);
}).ToList() != null;
条件结果永远不会是where
。即使null
中的list
中没有任何对象满足CheckName
中的条件,where
也会返回空集合。
答案 2 :(得分:1)
由于Linq的延迟执行,未执行CheckName()
方法。在您实际访问之前,不会执行实际的语句。因此,在您的情况下,对于CheckName()
,您应该执行以下操作:
var name = list.Where(n =>
{
return CheckName(n);
}).ToList();
答案 3 :(得分:0)
如果你需要为列表中的每个项目调用一个方法,那么你应该使用一个简单的for循环:
foreach var name in list
CheckName(name);
仅仅因为LINQ可用,并不意味着它应该在有集合的任何地方使用。编写有意义且自我评论的代码非常重要,并且在此处使用它同时在您的逻辑中引入了一个缺陷,使您的代码更难以阅读,理解和维护。它是用于所述目的的错误工具
毫无疑问,您有其他要求未在此处说明,例如&#34;我想检查列表中的每个名称,并确保没有任何名称为空&#34;。您可以并且可能应该使用linq,但它看起来更像
bool allNamesOK = list.All(n => n != null);
此代码紧凑且读取良好;我们可以清楚地看到意图(虽然我不打电话给列表&#34;列表&#34; - &#34;名字&#34;会更好)
答案 4 :(得分:0)
当您查看Where
- 方法source代码时,您可以轻松了解原因:
internal static IEnumerable<T> Where<T>(this IEnumerable<T> enumerable, Func<T, bool> where) {
foreach (T t in enumerable) {
if (where(t)) {
yield return t;
}
}
}
只有在实际访问返回的IEnumerable<T>
后,yield才会导致执行。这就是所谓的延迟执行。