C# 选择';使用Select(…)时会运行s方法。是否有(…)?
首先,我有这个代码,如果条件满足,它将中断第二个循环 例如,如果第一次满足条件,则第二个循环的其他元素将不会被枚举C# 选择';使用Select(…)时会运行s方法。是否有(…)?,c#,linq,C#,Linq,首先,我有这个代码,如果条件满足,它将中断第二个循环 例如,如果第一次满足条件,则第二个循环的其他元素将不会被枚举 foreach (var evaluator in strategyEvaluators) { foreach (var rule in concatedRules) { var isEntryRuleMet = evaluator.Evaluate(rule.Code); if (isEntryRuleMet) {
foreach (var evaluator in strategyEvaluators)
{
foreach (var rule in concatedRules)
{
var isEntryRuleMet = evaluator.Evaluate(rule.Code);
if (isEntryRuleMet)
{
matchedNames.Add(evaluator.Name);
break;
}
}
}
但我也发现代码可以通过这种方式缩短:
foreach (var evaluator in strategyEvaluators)
{
if (concatedRules.Select(rule=> evaluator.Evaluate(rule.Code)).Any(isEntryRuleMet => isEntryRuleMet))
{
matchedNames.Add(evaluator.Name);
}
}
注意,对于第二种方法,我不知道Select
方法将运行多少次
在Any
返回true后,Select
是否立即停止?或者它是否已完成运行,然后运行了Any
?
Select是否在返回true后立即停止?或者它运行完毕,然后运行任何一个
是的。您可以这样想:Select
向Any
生成元素,只要它返回false
,一旦返回true
,它就会停止。剩余的元素不会生成
下面是一个简单的程序来演示它:
public static void Main()
{
var query = Enumerable.Range(0,10).Select(x => GetNumber(x)).Any(x => x > 5);
}
public static int GetNumber(int x)
{
Console.WriteLine("GetNumber is called: {0}", x);
return x;
}
// Output:
GetNumber is called: 0
GetNumber is called: 1
GetNumber is called: 2
GetNumber is called: 3
GetNumber is called: 4
GetNumber is called: 5
GetNumber is called: 6
Select
将在满足Any
后停止运行。因此,一旦返回true,它就会跳出foreach循环,不再具体化集合
您甚至可能希望将代码编写为
foreach (var evaluator in strategyEvaluators)
{
if (concatedRules.Any(rule=>evaluator.Evaluate(rule.Code)))
{
matchedNames.Add(evaluator.Name);
}
}
这样,您甚至不必担心选择问题。当第一次
任何成功时,迭代就会停止
您甚至可以通过以下操作使代码更小:
var matchedNames =
strategyEvaluators
.Where(evaluator =>
concatedRules
.Where(rule => evaluator.Evaluate(rule.Code))
.Any())
.Select(evaluator => evaluator.Name)
.ToList();
如果已定义了matchedNames
,请尝试以下操作:
matchedNames
.AddRange(
strategyEvaluators
.Where(evaluator =>
concatedRules
.Where(rule => evaluator.Evaluate(rule.Code))
.Any())
.Select(evaluator => evaluator.Name));
是的,这被称为“惰性评估”,并且LINQtoObjects扩展方法尽可能努力使用惰性评估。一些没有(因为它们不能)的是ToList
、ToArray
、和OrderBy
.concatedRules.Where(rule=>evaluator.Evaluate(rule.code))。当我这样做时,Any()会更准确:concatedRules.Where(rule=>evaluator.Evaluate(rule.code)).Any(),而不是提示我这样做:concatedRules.Any()(rule=>strategyAlert.Evaluate(rule.Code))谢谢,这是正确的链接: