138 Stimmen

Warum gibt Enumerable.All für eine leere Sequenz true zurück?

var strs = new Collection<string>();
bool b = strs.All(str => str == "ABC");

Der Code erstellt eine leere Stringsammlung und versucht dann zu ermitteln, ob alle Elemente in der Sammlung "ABC" sind. Wenn Sie ihn ausführen, b wahr sein wird.

Aber die Sammlung enthält nicht einmal Elemente, geschweige denn Elemente, die "ABC" entsprechen.

Ist dies ein Fehler, oder gibt es eine vernünftige Erklärung?

3voto

AnorZaken Punkte 1637

Hier ist eine Erweiterung, die das tun kann, was OP tun wollte:

static bool All<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool mustExist)
{
    foreach (var e in source)
    {
        if (!predicate(e))
            return false;
        mustExist = false;
    }
    return !mustExist;
}

...und wie andere bereits gesagt haben, ist dies kein Fehler, sondern ein gut dokumentiertes, beabsichtigtes Verhalten.

Eine alternative Lösung, wenn man keine neue Erweiterung schreiben möchte, ist:

strs.DefaultIfEmpty().All(str => str == "ABC");

PS: Das obige funktioniert nicht, wenn man nach dem Standardwert selbst sucht! (Was bei Strings null wäre.) In solchen Fällen wird es weniger elegant mit etwas ähnlichem wie:

strs.DefaultIfEmpty(string.Empty).All(str => str == null);

Wenn Sie mehr als einmal aufzählen können, ist die einfachste Lösung:

strs.All(predicate) && strs.Any();

d.h. einfach eine Prüfung hinzufügen, ob es tatsächlich eine jede Element.

1voto

Muhammad Hasan Khan Punkte 33714

Von der Umsetzung einmal abgesehen. Ist es wirklich wichtig, ob es wahr ist? Sehen Sie, wenn Sie einen Code haben, der über die Aufzählungsliste iteriert und einen Code ausführt. Wenn All() wahr ist, wird dieser Code trotzdem nicht ausgeführt, da die Aufzählungsliste keine Elemente enthält.

var hungryDogs = Enumerable.Empty<Dog>();
bool allAreHungry = hungryDogs.All(d=>d.Hungry);    
if (allAreHungry)
    foreach (Dog dog in hungryDogs)
         dog.Feed(biscuits); <--- this line will not run anyway.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X