LINQ:不是任何还是所有都不要 [英] LINQ: Not Any vs All Don't

查看:21
本文介绍了LINQ:不是任何还是所有都不要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Often I want to check if a provided value matches one in a list (e.g. when validating):

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

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

Recently, I've noticed ReSharper asking me to simplify these queries to:

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

显然,这在逻辑上是相同的,也许可读性稍强一些(如果你已经做了很多数学),我的问题是:这会导致性能下降吗?

Obviously, this is logically identical, perhaps slightly more readable (if you've done a lot of mathematics), my question is: does this result in a performance hit?

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

It feels like it should (i.e. .Any() sounds like it short-circuits, whereas .All() sounds like it does not), but I have nothing to substantiate this. Does anyone have deeper knowledge as to whether the queries will resolve the same, or whether ReSharper is leading me astray?

推荐答案

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

Implementation of All according to ILSpy (as in I actually went and looked, rather than the "well, that method works a bit like ..." I might do if we were discussing the theory rather than the impact).

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 的明显反转.

Of course, there could be some subtle difference in the IL produced. But no, no there isn't. The IL is pretty much the same but for the obvious inversion of returning true on predicate match versus returning false on predicate mismatch.

这当然只是 linq-for-objects.其他一些 linq 提供程序可能会比另一个更好地对待一个,但如果是这种情况,那么哪个获得更优化的实现几乎是随机的.

This is linq-for-objects only of course. It's possible that some other linq provider treats one much better than the other, but then if that was the case, it's pretty much random which one got the more optimal implementation.

似乎该规则完全归结为某人认为 if(determineSomethingTrue)if(!determineSomethingFalse) 更简单、更具可读性.公平地说,我认为他们有点道理,因为我经常发现 if(!someTest) 令人困惑* 当有一个同等冗长和复杂性的替代测试会为条件返回 true 时我们想采取行动.然而,实际上,我个人认为没有什么比你给出的两种选择中的另一种更偏向于另一种,如果谓词更复杂,我可能会略微倾向于前者.

It would seem that the rule comes down solely to someone feeling that if(determineSomethingTrue) is simpler and more readable than if(!determineSomethingFalse). And in fairness, I think they've a bit of a point in that I often find if(!someTest) confusing* when there's an alternative test of equal verbosity and complexity that would return true for the condition we want to act upon. Yet really, I personally find nothing to favour one over the other of the two alternatives you give, and would perhaps lean very slightly toward the former if the predicate were more complicated.

*不是因为我不明白而令人困惑,而是因为我担心有一些我不理解的决定的微妙原因而令人困惑,并且需要进行一些心理跳跃才能意识到不,他们只是决定这样做,等等,我又在看这段代码是为了什么?......"

*Not confusing as in I don't understand, but confusing as in I worry that there's some subtle reason for the decision that I don't understand, and it takes a few mental skips to realise that "no, they just decided to do it that way, wait what was I looking at this bit of code for again?..."

这篇关于LINQ:不是任何还是所有都不要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆