请考虑以下事项:
bool invalidChildren = this.Children.Any(c => !c.IsValid());
此类具有一组具有IsValid()
方法的子对象。假设IsValid()
方法是处理器密集型任务。在遇到IsValid()
为false
的第一个子对象后,理论上处理可以停止,因为结果永远不会变为真。 LINQ to对象实际上是在第一个IsValid() = false
之后(如逻辑AND)停止计算还是继续评估所有子对象?
显然我可以把它放在一个foreach循环中并打破第一个无效结果,但我只是想知道对象的LINQ是否足够聪明来做到这一点。
修改 感谢您的回答,出于某种原因,我不想在MSDN上查找它。
答案 0 :(得分:21)
是的。一旦找到匹配,标准就会满足。 All
的相似之处在于它会检查所有项目,但如果一项不匹配,它也会立即结束。
Exists
也以同样的方式运作。
一旦确定结果,就会停止源的枚举。
当前List的元素分别传递给Predicate委托,并在找到匹配时停止处理。
一旦确定结果,就会停止源的枚举。
等...
答案 1 :(得分:6)
是的,只要评估结果就会停止。这是一个快速证明:
class Program
{
static void Main(string[] args)
{
bool allvalid = TestClasses().Any(t => !t.IsValid());
Console.ReadLine();
}
public static IEnumerable<TestClass> TestClasses()
{
yield return new TestClass() { IsValid = () => { Console.Write(string.Format("TRUE{0}",Environment.NewLine)); return true; } };
yield return new TestClass() { IsValid = () => { Console.Write(string.Format("FALSE{0}", Environment.NewLine)); return false; } };
yield return new TestClass() { IsValid = () => { Console.Write(string.Format("TRUE{0}", Environment.NewLine)); return true; } };
yield return new TestClass() { IsValid = () => { Console.Write(string.Format("TRUE{0}", Environment.NewLine)); return true; } };
}
}
public class TestClass
{
public Func<bool> IsValid {get;set;}
}
答案 2 :(得分:2)
答案 3 :(得分:1)
根据MSDN
,
只要可以确定结果, source 的枚举就会停止。
答案 4 :(得分:1)
这是一个快速而肮脏的实证测试,可以自己看看:
class Kebab
{
public static int NumberOfCallsToIsValid = 0;
public bool IsValid()
{
NumberOfCallsToIsValid++;
return false;
}
}
...
var kebabs = new Kebab[] { new Kebab(), new Kebab() };
kebabs.Any(kebab => !kebab.IsValid());
Debug.Assert(Kebab.NumberOfCallsToIsValid == 1);
结果是肯定的,Any
LINQ运算符会在集合项与谓词匹配时立即停止。