2
    class Program
    {
        static void Main()
        {
            var list = new List<Foo>();
            var a = list.All(l => l.BoolBar == true);//true
            var s = list.All(l => l.Bar.Contains("magicstring"));//true
        }
    }
    public class Foo
    {
        public bool BoolBar{ get; set; }
        public string Bar{ get; set; }
    }

Based on this snippet I'm wondering why Linq framework creators chose to go with this solution for empty collections? Also, due Visual Studio and Linq are both MS products why intellisense does not warn if a user didn't check whether the collection is empty before performing .All? I think it can cause a lot of unexpected results.

OlegI
  • 5,472
  • 4
  • 23
  • 31
  • 1
    @Sinatr That would be the same because `Any` returns `false` for an empty collection. – juharr Nov 15 '17 at 14:28
  • `Enumerable.All`'s purpose is not to check if the collection is empty, therefore you can use `list.Count`. It checks if all items in the collection match a certain predicate. Why it would be correct to say that items don't match if there are no items? This is the simple implementation of the logic: `foreach(var x in items) if(!predicate(x)) return false; return true;` – Tim Schmelter Nov 15 '17 at 14:29
  • I'm not looking for the solution of to how to avoid this. The question is why this is default behavior? Probably someone has a proper explanation, would be eager to read it. – OlegI Nov 15 '17 at 14:36
  • 1
    @Sinatr In the OP's case that would throw an null reference exception unless they change the condition to handle that case. – juharr Nov 15 '17 at 14:36
  • @OlegI: well, you noticed that this question is lready closed because it's a duplicate? But my last comment doesnt make it clearer? – Tim Schmelter Nov 15 '17 at 14:39
  • Part of the reason is that `All` and `Any` are meant to be opposites. So would you expect `Any` to return true for an empty collection? No. – juharr Nov 15 '17 at 14:41
  • @juharr: that's not a good explanation, they aren't oposites, they check two different things. All=all must match, Any=At least one must match. The opposite of `All` would be `!Any`. But even then it doesn't mean that All must behave the same/opposite with empty collections. – Tim Schmelter Nov 15 '17 at 14:42
  • @TimSchmelter I'm talking about how `x.All(y => z) == !x.Any(y => !z)`. So maybe it's not as obvious that `All` on an empty collection is `true`, but it should be obvious that `Any` on an empty collection is `false`. – juharr Nov 15 '17 at 14:46
  • @juharr: yes, but it's still not so helpful to explain something by the opposite. The question is: what should `Enumerable.All` return if there are no items to check, but the caller wants to know if all items match a condition? The devolopers decided that it's "more correct" to answer that it's `true` than `false`. The only correct answer would have been this counterquestion: "it's empty so why you ask me?". So if that matters you have to answer this yourself by using `list.Count > 0` or `list.Any()`. – Tim Schmelter Nov 15 '17 at 14:55

1 Answers1

6

That's what the Documentation says.

true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, false.

Implementation:

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 element in source) {
        if (!predicate(element)) return false;
    }
    return true;
}

So it's obvious, if there is no item in the IEnumerable the foreach loop will be skipped and it directly returns true.

fubo
  • 44,811
  • 17
  • 103
  • 137