所以我遇到了今天的情况,其中一些生产代码正在失败,因为一个方法完全按照MSDN中的说明执行.因为没有阅读文档而感到羞耻.然而,我仍然在摸索为什么它会以这种方式行事,即使是"按设计",因为这种行为正好与我预期的(和其他已知行为)相反,因此似乎违反了原则最不惊讶的.
该All()方法允许您提供谓词(例如lambda表达式)来测试IQueryable,返回一个布尔值,指示所有集合成员是否与测试匹配.到现在为止还挺好.这就是它变得奇怪的地方. 如果集合为空,All()也会返回true.由于以下原因,这似乎完全落后于我:
Any()方法按预期行为,并且(正确)返回false,因为它没有任何与谓词匹配的成员.所以我的问题是,为什么All()这样做?它解决了什么问题?这是否违反了最不惊讶的原则?
我将此问题标记为.NET 3.5,但该行为也适用于.NET 4.0.
编辑 好的,所以我掌握了这个逻辑方面,正如杰森和你们其他人所做的那样.不可否认,空集合是一种边缘情况.我想我的问题根植于斗争,只是因为某些东西是合乎逻辑的并不意味着如果你没有处于正确的思维框架中,它必然是有道理的.
jas*_*son 43
如果我的车道是空的,我不能断言停在那里的所有车都是红色的.
请考虑以下陈述.
S1:我的车道是空的.
S2:停在车道上的所有车都是红色的.
我声称这S1意味着S2.也就是说,陈述S1 => S2是真的.我将通过表明其否定是错误来做到这一点.在这种情况下,否定S1 => S2是S1 ^ ~S2; 这是因为S1 => S2只有当S1为真且S2为假时才是假的.什么是否定S2?它是
~S2:车道上停着一辆不是红色的车.
什么是真值S1 ^ ~S2?我们把它写出来吧
S1 ^ ~S2:我的车道是空的,车道上停着一辆不是红色的车.
唯一的方法S1 ^ ~S2可以是真实的是,如果这两个S1和~S2是真实的.但是S1说我的车道是空的,并且S2说我的车道上有一辆车.我的车道不能都是空的并且包含一辆车.因此,它是不可能S1和~S2双方是真实的.因此,S1 ^ ~S2是假的,所以它的否定S1 => S2是正确的.
因此,如果您的车道是空的,您可以断言停在那里的所有车辆都是红色的.
所以现在让我们考虑一个IEnumerable<T> elements和一个Predicate<T> p.让我们假设这elements是空的.我们希望发现它的价值
bool b = elements.All(x => p(x));
Run Code Online (Sandbox Code Playgroud)
让我们考虑一下它的否定
bool notb = elements.Any(x => !p(x));
Run Code Online (Sandbox Code Playgroud)
对于notb是真实的,必须有至少一个x在elements为这!p(x)是真的.但是elements是空的,所以它是不可能找到一个x为这!p(x)是真的.因此notb不可能是真的,所以一定是假的.既然notb是假的,那么它的否定就是真的.因此b是真的,elements.All(x => p(x))如果elements是空的则必须为真.
这是另一种思考方式.谓词p如果是真实的一切 x在elements你找不到任何为它是假的.但如果当时没有任何物品,elements则无法找到任何错误的物品.因此,对于一个空的集合elements,p是真正为所有 x的elements
现在,约elements.Any(x => p(x))当elements是一个空IEnumerable<T>并且p是Predicate<T>如上?我们已经知道结果将是错误的,因为我们知道它的否定是正确的,但无论如何我们都要通过它来推理它.直觉很有价值.对于elements.Any(x => p(x))是真实的,必须有至少一个x在elements为这p(x)是真的.但是,如果没有任何 x在elements它是不可能找到任何 x针对这p(x)是真的.因此,elements.Any(x => p(x))如果elements是空的则为假.
最后,这里有一个相关的解释,为什么s.StartsWith(String.Empty)当s一个非null实例时为真string:
Des*_*ted 10
如果返回的项目true数与所有项目的数量相同,则返回true.就那么简单:
Driveway.Cars(a => a.Red).Count() == Driveway.Cars.Count()
Run Code Online (Sandbox Code Playgroud)
相关解释:为什么"abcd".StartsWith("")返回true?
Any()和All()只是常用数学运算符 \xe2\x88\x83 (“存在限定符”或“存在”)和 \xe2\x88\x80 (“通用限定符”或“对于所有人”)的实现。
“任何”意味着存在某个谓词为真的项目。对于空集合,这是错误的。
\n\n“全部”意味着不存在任何谓词为假的项目。对于空集合来说,这始终是正确的。
\n"如果收集是空的,那么这样的测试充其量是不确定的.如果我的车道是空的,我不能断言停在那里的所有车都是红色的."
是的你可以.
为了证明我的错,请在空车道上给我看一辆不是红色的车.
对于熟悉SQL概念的人来说,NULL!= NULL,这是意外的行为.
这是SQL的一个怪癖(并不完全正确:NULL = NULL并且NULL <> NULL都是未定义的,并且都不会匹配任何行.)