Any <T>的相反方法是什么


80

如何使用Linq检查集合中是否不包含对象。IE的反义词Any<T>

我可以使用来反转结果,!但是出于可读性考虑,我想知道是否还有更好的方法吗?我应该自己添加扩展名吗?


然后更具可读性!ContainsExists
Tigran 2012年

3
是的,没有None<T>。我经常使用这种定制扩展可读性(例如我不喜欢的!dictionary.ContainsKey(key)语法,所以我实现dictionary.NoKey(key)吧。
康拉德·莫拉夫斯基

2
@Morawski:我已经开始使用ConcurrentDictionary,因为它是非常方便的GetOrAdd方法,即使我不需要并发。
罗杰·利普斯科姆2012年

Answers:


87

您可以轻松创建None扩展方法:

public static bool None<TSource>(this IEnumerable<TSource> source)
{
    return !source.Any();
}

public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    return !source.Any(predicate);
}

1
我觉得这将是对标准Linq的不错的补充。
伊万2015年

2
@Ivan,它不在Linq本身中,但是它属于我的Linq.Extras
Thomas Levesque

60

验证任何(至少一个)记录均符合特定条件的相反操作将是验证所有记录均不符合条件。

您没有发布完整的示例,但是如果您想要与之相反的内容:

var isJohnFound = MyRecords.Any(x => x.FirstName == "John");

您可以使用:

var isJohnNotFound = MyRecords.All(x => x.FirstName != "John");

刚刚在Google上今天遇到了这个问题,尽管我同意您的方法,但我通常会使用var isJohnNotFound = !MyRecords.All(x => x.FirstName == "John");
克里斯(Chris)

当然,我很无聊。当我这样做时,并没有检查单个字段。通常情况更像是这样,!MyRecords.All(x => InvalidNames.Any(n => n == x.Name));所以请对照无效名称列表检查每个条目,只有在没有匹配项的情况下,结果才为true。
克里斯,

2

除了添加的答案外,如果不想包装Any()方法,还可以None()按以下方式实现:

public static bool None<TSource>(this IEnumerable<TSource> source) 
{
    if (source == null) { throw new ArgumentNullException(nameof(source)); }

    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        return !enumerator.MoveNext();
    }
}

public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null) { throw new ArgumentNullException(nameof(source)); }
    if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); }

    foreach (TSource item in source)
    {
        if (predicate(item))
        {
            return false;
        }
    }

    return true;
}

除了无参数重载之外,您还可以应用ICollection<T>优化,而这在LINQ实现中实际上是不存在的。

ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null) { return collection.Count == 0; }

2

发现这个线程时,我想知道,如果一个集合不包含一个对象,但我也不会要检查所有的集合中的对象符合给定的标准。我最终做了这样的检查:

var exists = modifiedCustomers.Any(x => x.Key == item.Key);

if (!exists)
{
    continue;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.