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?

203voto

Jon Skeet Punkte 1325502

Es ist sicherlich kein Fehler. Es verhält sich genau so wie dokumentiert :

true, wenn jedes Element der Quellsequenz den Test im angegebenen Prädikat besteht, oder wenn die Sequenz leer ist ; sonst falsch.

Nun kann man darüber streiten, ob es debe auf diese Weise funktionieren (es scheint mir in Ordnung zu sein; jedes Element der Sequenz entspricht dem Prädikat), aber die als allererstes zu prüfen Bevor man fragt, ob etwas ein Fehler ist, sollte man sich die Dokumentation ansehen. (Sie ist das erste, was man überprüft, sobald sich eine Methode anders verhält als erwartet.)

22voto

Mr. Putty Punkte 2176

All erfordert, dass das Prädikat für alle Elemente der Sequenz wahr ist. Dies wird in der Dokumentation ausdrücklich erwähnt. Es ist auch das Einzige, das Sinn macht, wenn man sich vorstellt All wie ein logisches "und" zwischen den Ergebnissen des Prädikats für jedes Element. Die true für die leere Sequenz ist das Identitätselement der Operation "und". Ebenso ist die false erhalten Sie von Any für die leere Folge ist die Identität für das logische "oder".

Wenn Sie an Folgendes denken All als "es gibt keine Elemente in der Sequenz, die keine sind", könnte dies mehr Sinn ergeben.

11voto

leppie Punkte 111830

Es true denn nichts (keine Bedingung) macht es false .

Die Dokumentation erklärt es wahrscheinlich. (Jon Skeet hat vor ein paar Jahren auch etwas erwähnt)

Das Gleiche gilt für Any (das Gegenteil von All ) Rückkehr false für leere Mengen.

Edita:

Sie können sich vorstellen All semantisch gleich implementiert werden wie:

foreach (var e in elems)
{
  if (!cond(e))
    return false;
}
return true; // no escape from loop

8voto

Juan Punkte 14812

Die meisten Antworten hier scheinen zu lauten: "Weil es so definiert ist". Aber es gibt auch einen logischen Grund, warum das so definiert ist.

Bei der Definition einer Funktion sollten Sie darauf achten, dass die Funktion so allgemein wie möglich ist, damit sie auf eine möglichst große Anzahl von Fällen angewendet werden kann. Nehmen wir zum Beispiel an, ich möchte die Funktion Sum Funktion, die die Summe aller Zahlen in einer Liste liefert. Was soll sie zurückgeben, wenn die Liste leer ist? Wenn Sie eine beliebige Zahl zurückgeben würden x würden Sie die Funktion als die definieren:

  1. Funktion, die die Summe aller Zahlen in der angegebenen Liste zurückgibt, oder x wenn die Liste leer ist.

Aber wenn x Null ist, können Sie ihn auch als

  1. Funktion, die Folgendes zurückgibt x plus die angegebenen Zahlen.

Man beachte, dass Definition 2 Definition 1 impliziert, aber 1 nicht 2 impliziert, wenn x nicht Null ist, was an sich schon Grund genug ist, 2 gegenüber 1 zu bevorzugen. Aber beachten Sie auch 2 ist eleganter und ist an sich allgemeiner als 1. Es ist, als würde man einen Scheinwerfer weiter weg aufstellen, damit er einen größeren Bereich ausleuchtet. Sehr viel größer sogar. Ich bin selbst kein Mathematiker, aber ich bin mir sicher, dass sie eine Menge Verbindungen zwischen Definition 2 und anderen mathematischen Konzepten finden werden, aber nicht so viele im Zusammenhang mit Definition 1, wenn x nicht Null ist.

Im Allgemeinen können und wollen Sie die Einzelelement (diejenige, die den anderen Operanden unverändert lässt), wenn Sie eine Funktion haben, die einen binären Operator auf eine Menge von Elementen anwendet und die Menge leer ist. Dies ist derselbe Grund, warum eine Product Funktion gibt 1 zurück, wenn die Liste leer ist (beachten Sie, dass Sie auch einfach " x plus" mit "ein Mal" in Definition 2). Und ist der gleiche Grund All (was man sich als wiederholte Anwendung des logischen Operators AND vorstellen kann) ergibt true wenn die Liste leer ist ( p && true ist gleichbedeutend mit p ), und aus demselben Grund Any (der OR-Operator) liefert false .

4voto

Andrew Barber Punkte 38387

Die Methode durchläuft alle Elemente, bis sie eines findet, das die Bedingung nicht erfüllt, oder bis sie keines findet, das nicht funktioniert. Wenn keines der Elemente fehlschlägt, wird true zurückgegeben.

Wenn also keine Elemente vorhanden sind, wird true zurückgegeben (da keine Elemente fehlgeschlagen sind)

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