Runtime: Would like IEnumerable.None as part of the standard.

Created on 18 Oct 2018  路  11Comments  路  Source: dotnet/runtime

From standard created by tbrettallen : dotnet/standard#509

For the sake of code clarity, my team uses an IEnumerable extension method None instead of !Any().

Currently our implementation is:

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

While it might be superfluous, ReSharper and other code analytics tools don't recognize this when analyzing LINQ statements. For example, it has many times suggested changing All(x => x.y != z) into !Any(x => x.y == z).

I feel this would be a simple to implement standard method for the IEnumerable interface and allow for easier to read code.

api-suggestion area-System.Linq

Most helpful comment

I understand the original reasoning, but I don't think we should be in the business of adding new APIs that are effectively just differently-named forwarders to existing APIs. They add very little value and could be done by any developer in any library with as good an implementation as the core libraries can provide. While adding little value without downsides is something to consider, there are downsides here: additional surface area a developer needs to learn, potential confusion as to when to use None vs !Any, inability to write code to a lower .NET Standard version when such a lower version could easily targeted by using the existing named API, etc.

All 11 comments

@cston, @333fred PTAL.

Then there should be Some as well :)
C# public static bool Some<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { return !source.All<TSource>(predicate); }

@omariom - Probably can't call it Some? I feel like I want that method to have the same behavior as Any.

The name would have to be OnlySome which isn't really clearer than NotAll.

I think the point was that None() is easier to read that !Any().

Some() would be identical to Any(), no?

Some() would mean Any(). OnlySome() would mean !All() which is what @omariom was after to complete the square (Any, All, NotAny, NotAll). As in, "only some of these objects are red." I'm not sure it's any clearer than !All(), particularly when none (not some) are red.

I understand the original reasoning, but I don't think we should be in the business of adding new APIs that are effectively just differently-named forwarders to existing APIs. They add very little value and could be done by any developer in any library with as good an implementation as the core libraries can provide. While adding little value without downsides is something to consider, there are downsides here: additional surface area a developer needs to learn, potential confusion as to when to use None vs !Any, inability to write code to a lower .NET Standard version when such a lower version could easily targeted by using the existing named API, etc.

If the BCL ever adds Optional<>, Optional<>.None would be more like Enumerable.Empty<> than like IEnumerable<>.None. Even though the name is the same.

We have .Any with and without a predicate. So we should have .None with and without a predicate.

Personally, I would probably use .None() more often than .None(bool).

They add very little value and could be done by any developer in any library with as good an implementation as the core libraries can provide.

The value is clarity of intent. Consider this example:

        var b1 = !dataSource.Root.Child[0].Grandchildern.Any(x => x ^ 2 > 3);
        var b2 = dataSource.Root.Child[0].Grandchildern.None(x => x ^ 2 > 3);

With b1 it is really easy to miss that not operator. It is meant to apply to the Any operation, but it is all the way over on the other side of the expression chain.


This is such a common issue that every project I've joined since LINQ was created has a None extension method, and often more than one.

Thank you for the suggestion, but we're not going to proceed with this. While the existing naming may not be to everyone's liking, this suggestion and variations of it are all accomplishable with Any, All, !Any, and !All. The benefit to adding additional method that exist just to provide different names doesn't outweigh the costs, both to the implementers/maintainers of that functionality and to consumers now having to see/learn about the increased surface area.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matty-hall picture matty-hall  路  3Comments

nalywa picture nalywa  路  3Comments

omariom picture omariom  路  3Comments

aggieben picture aggieben  路  3Comments

GitAntoinee picture GitAntoinee  路  3Comments