我经常想判断提供的值是否与列表中的值匹配(例如,在验证时):

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

最近,我注意到ReSharper要求我将这些查询简化为:

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

显然,这在逻辑上是相同的,也许可读性稍好一些(如果您做了大量数学计算),我的问题是:这是否会影响性能?

感觉应该是这样的(即.Any()听起来像短路,而.All()听起来像不短路),但我没有什么可以证实这一点.有没有人对这些问题是否能解决同样的问题有更深入的了解,或者ReSharper是否正把我引入歧途?

推荐答案

根据ILSpy实现All(就像我实际go 看的那样,而不是"好吧,这个方法有点像……"如果我们讨论的是理论,而不是影响,我可能会这么做).

public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    foreach (TSource current in source)
    {
        if (!predicate(current))
        {
            return false;
        }
    }
    return true;
}

根据ILSpy实施Any:

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    foreach (TSource current in source)
    {
        if (predicate(current))
        {
            return true;
        }
    }
    return false;
}

当然,在产生的IL中可能会有一些细微的差异.但是,不,没有.IL几乎相同,除了在谓词匹配上返回TRUE和在谓词不匹配上返回FALSE这两个明显的反转之外.

当然,这是linq仅适用于对象.有可能其他linq提供者对其中一个的处理比另一个好得多,但如果是这样的话,那么哪一个得到了更好的实现几乎是随机的.

这条规则似乎完全取决于那些觉得if(determineSomethingTrue)if(!determineSomethingFalse)更简单、可读性更强的人.公平地说,我认为他们有一点道理,因为我经常发现if(!someTest)令人困惑,当有另一种同样冗长和复杂的测试时,对于我们想要采取行动的条件,它会返回TRUE.然而,实际上,我个人认为,在您给出的两个 Select 中,没有什么比另一个更有利的,如果谓词更复杂,我可能会非常稍微倾向于前者.

*不是像我不理解那样令人困惑,而是像在我担心做出这个决定有一些我不理解的微妙原因,需要几次心理 skip 才能意识到"不,他们只是决定那样做,等等,我再看一遍这段代码是为了什么?"

.net相关问答推荐

EF核心类似功能T-SQL UPDATE FROM

如何在 Raspberry Pi 上托管 WASM 文件?

正则表达式在空格上拆分,除非在引号中

无法解析此引用.找不到程序集

process.WaitForExit() 异步

.NET 的 Visual Studio 调试器提示和技巧

有什么方法可以使用 .NET 应用程序使用 git 吗?

Silverlight 与 Flex

序列化私有成员数据

读取方法的属性值

基于多个字符分隔符拆分字符串

双倍的? = 双倍? + 双倍?

.NET 事件 - 什么是对象发送者和 EventArgs e?

如何禁用 Alt + F4 关闭表单?

C#As的 VB.NET 类似功能

DataGridView 在我的两个屏幕之一上的可怕重绘性能

如何从其十六进制 RGB 字符串创建 System.Drawing.Color?

使 HashSet 不区分大小写

MailMessage,Sender 和 From 属性的区别

在不使用while循环的情况下找到最里面的异常?