Sollte ich leere Sammlungen in meinen Methoden akzeptieren, die über sie iterieren?

40

Ich habe eine Methode, bei der die gesamte Logik in einer foreach-Schleife ausgeführt wird, die den Parameter der Methode durchläuft:

public IEnumerable<TransformedNode> TransformNodes(IEnumerable<Node> nodes)
{
    foreach(var node in nodes)
    {
        // yadda yadda yadda
        yield return transformedNode;
    }
}

In diesem Fall führt das Einreichen einer leeren Sammlung zu einer leeren Sammlung, aber ich frage mich, ob das nicht klug ist.

Meine Logik hier ist, dass, wenn jemand diese Methode aufruft, er beabsichtigt, Daten weiterzuleiten, und nur unter irrtümlichen Umständen eine leere Auflistung an meine Methode übergeben würde.

Sollte ich dieses Verhalten abfangen und eine Ausnahme auslösen, oder ist es empfehlenswert, die leere Auflistung zurückzugeben?

Nick Udell
quelle
43
Sind Sie sicher, dass Ihre Annahme "Wenn jemand diese Methode aufruft, beabsichtigt er, Daten weiterzuleiten" richtig ist? Vielleicht übergeben sie nur das, was sie zur Hand haben, um mit dem Ergebnis zu arbeiten.
SpaceTrucker
7
Übrigens: Ihre "Transformation" -Methode wird normalerweise als "Map" bezeichnet, obwohl sie in .NET (und SQL, von dem .NET den Namen hat) im Allgemeinen als "select" bezeichnet wird. "Transformieren" nennt man das in C ++, aber das ist kein gebräuchlicher Name, den man vielleicht kennt.
Jörg W Mittag
25
Ich würde werfen, wenn die Sammlung ist, nullaber nicht, wenn sie leer ist.
CodesInChaos
21
@NickUdell - Ich gebe die ganze Zeit leere Sammlungen in meinem Code weiter. In Fällen, in denen ich meiner Sammlung nichts hinzufügen konnte, bevor ich fortfuhr, ist es für Code einfacher, sich gleich zu verhalten als eine spezielle Verzweigungslogik zu schreiben.
theMayer
7
Wenn Sie überprüfen und einen Fehler auslösen, wenn die Auflistung leer ist, zwingen Sie Ihren Aufrufer, auch eine leere Auflistung zu überprüfen und nicht an Ihre Methode zu übergeben. Überprüfungen sollten an (und nur an) Systemgrenzen durchgeführt werden. Wenn leere Sammlungen Sie stören, sollten Sie sie bereits lange vor Erreichen von Dienstprogrammmethoden überprüft haben. Jetzt haben Sie zwei redundante Prüfungen.
Lie Ryan

Antworten:

175

Dienstprogrammmethoden sollten keine leeren Sammlungen verwenden. Ihre API-Kunden würden Sie dafür hassen.

Eine Sammlung kann leer sein. Eine "Sammlung, die nicht leer sein darf" ist konzeptionell viel schwieriger zu bearbeiten.

Das Transformieren einer leeren Sammlung hat ein offensichtliches Ergebnis: die leere Sammlung. (Sie können sogar etwas Müll sparen, indem Sie den Parameter selbst zurückgeben.)

Es gibt viele Umstände, unter denen ein Modul Listen von Dingen führt, die möglicherweise bereits mit etwas gefüllt sind oder nicht. Vor jedem Anruf auf Leere prüfen zu müssen, transformist ärgerlich und kann dazu führen, dass ein einfacher, eleganter Algorithmus zu einem hässlichen Durcheinander wird.

Utility-Methoden sollten immer danach streben, in ihren Eingaben liberal und in ihren Ausgaben konservativ zu sein.

Gehen Sie aus all diesen Gründen, um Himmels willen, korrekt mit der leeren Sammlung um. Nichts ist ärgerlicher als ein Hilfsmodul, das denkt, es weiß, was Sie wollen, besser als Sie.

Kilian Foth
quelle
14
+1 - (mehr wenn ich könnte). Ich könnte sogar so weit gehen, dass ich mich nullin die leere Sammlung einfüge. Funktionen mit impliziten Einschränkungen sind ein Schmerz.
Telastyn
6
"Nein, solltest du nicht" ... sollst sie nicht akzeptieren oder sollst keine Ausnahme machen?
Ben Aaronson
16
@Andy - das wären allerdings keine Utility- Methoden. Das wären Geschäftsmethoden oder ein ähnliches konkretes Verhalten.
Telastyn
38
Ich halte es nicht für eine gute Idee, die leere Sammlung für eine Rücksendung zu recyceln. Sie sparen nur wenig Speicherplatz. und es könnte zu unerwartetem Verhalten beim Anrufer führen. Beispiel: Populate1(input); output1 = TransformNodes(input); Populate2(input); output2 = TransformNodes(input); Wenn Populate1 die Auflistung leer lässt und Sie sie für den ersten TransformNodes-Aufruf zurückgeben, sind Ausgabe1 und Eingabe dieselbe Auflistung, und wenn Populaten2 aufgerufen wird, wenn Knoten in die Auflistung eingefügt werden, erhalten Sie die zweite Set von Input in Output2.
Dan Neely
6
@Andy Auch wenn das Argument niemals leer sein sollte - wenn es ein Fehler ist, keine zu verarbeitenden Daten zu haben - dann ist es meines Erachtens die Verantwortung des Aufrufers , dies zu überprüfen, wenn dieses Argument zusammengestellt wird. Dadurch wird diese Methode nicht nur eleganter, sondern es kann auch eine bessere Fehlermeldung (besserer Kontext) generiert und auf eine ausfallsichere Weise ausgelöst werden. Für eine nachgelagerte Klasse ist es nicht sinnvoll, die Invarianten des Anrufers zu überprüfen ...
Andrzej Doyle
26

Ich sehe zwei wichtige Fragen, die die Antwort darauf bestimmen:

  1. Kann Ihre Funktion irgendetwas Sinnvolles und Logisches zurückgeben, wenn eine leere Sammlung (einschließlich Null ) übergeben wird?
  2. Was ist der allgemeine Programmierstil in dieser Anwendung / Bibliothek / Team? (Insbesondere, wie FP sind Sie?)

1. Sinnvolle Rendite

Wenn Sie etwas Sinnvolles zurückgeben können, geben Sie im Wesentlichen keine Ausnahme aus. Lassen Sie den Anrufer mit dem Ergebnis umgehen. Also, wenn Ihre Funktion ...

  • Zählt die Anzahl der Elemente in der Auflistung und gibt 0 zurück. Das war einfach.
  • Sucht nach Elementen, die bestimmten Kriterien entsprechen, und gibt eine leere Sammlung zurück. Bitte werfen Sie nichts. Der Anrufer verfügt möglicherweise über eine große Sammlung von Sammlungen, von denen einige leer sind, andere nicht. Der Aufrufer möchte alle übereinstimmenden Elemente in einer Sammlung haben. Ausnahmen machen dem Anrufer nur das Leben schwerer.
  • Sucht nach den größten / kleinsten / am besten zu den Kriterien in der Liste passenden. Hoppla. Abhängig von der Frage nach dem Stil können Sie hier eine Ausnahme auslösen oder null zurückgeben . Ich hasse null (sehr viel eine FP-Person), aber es ist hier wohl sinnvoller und Sie können Ausnahmen für unerwartete Fehler in Ihrem eigenen Code reservieren. Wenn der Anrufer nicht auf null prüft, kommt es trotzdem zu einer ziemlich eindeutigen Ausnahme. Aber das überlässt du ihnen.
  • Fragt nach dem n-ten Element in der Sammlung oder den ersten / letzten n Elementen. Dies ist der beste Fall für eine Ausnahme und der, der den Anrufer am wenigsten verwirrt und erschwert. Es kann immer noch ein Fall für null gemacht werden, wenn Sie und Ihr Team es gewohnt sind, dies aus allen im vorherigen Punkt genannten Gründen zu überprüfen. Dies ist jedoch der bisher gültigste Fall, um eine DudeYou Know YouShouldCheckTheSizeFirst- Ausnahme auszulösen . Wenn Ihr Stil funktionaler ist, dann entweder null oder lesen Sie meine Antwort auf Stil weiter .

Im Allgemeinen sagt mir mein FP-Bias "etwas Sinnvolles zurückgeben" und Null kann in diesem Fall eine gültige Bedeutung haben.

2. Stil

Befürwortet Ihr allgemeiner Code (oder der Code des Projekts oder des Teams) einen funktionalen Stil? Wenn nein, werden Ausnahmen erwartet und behandelt. Wenn ja, können Sie einen Optionstyp zurückgeben . Bei einem Optionstyp geben Sie entweder eine aussagekräftige Antwort oder None / Nothing zurück . In meinem dritten Beispiel von oben wäre Nichts eine gute Antwort im FP-Stil. Die Tatsache, dass die Funktion einen Optionstyp zurückgibt, signalisiert dem Anrufer möglicherweise eindeutig, dass es sich um eine aussagekräftige Antwort handelt, und dass der Anrufer darauf vorbereitet sein sollte, damit umzugehen. Ich glaube, es gibt dem Anrufer mehr Möglichkeiten (wenn Sie das Wortspiel verzeihen).

F # ist , wo alle kühlen .Net Kinder diese Art der Sache zu tun , aber C # tut unterstützen diesen Stil.

tl; dr

Bewahren Sie Ausnahmen für unerwartete Fehler in Ihrem eigenen Codepfad auf, nicht vollständig vorhersehbare (und zulässige) Eingaben von Dritten.

itsbruce
quelle
"Beste Anpassung" usw .: Möglicherweise haben Sie eine Methode, die das am besten passende Objekt in einer Sammlung findet, das einem Kriterium entspricht. Diese Methode hätte das gleiche Problem für nicht leere Sammlungen, da möglicherweise nichts dem Kriterium entspricht, sodass Sie sich keine Gedanken über leere Auswahlen machen müssen.
gnasher729
1
Nein, aus diesem Grund habe ich gesagt: "Best Fit" und nicht "Matching". Die Phrase impliziert die engste Annäherung, keine exakte Übereinstimmung. Die größte / kleinste Option hätte ein Hinweis sein müssen. Wenn nur ¨best fit¨ angefragt wurde, sollte jede Sammlung mit 1 oder mehr Mitgliedern in der Lage sein, ein Mitglied zurückzugeben. Wenn es nur ein Mitglied gibt, passt das am besten.
Itsbruce
1
Rückgabe "null" ist in den meisten Fällen schlechter als das Auslösen einer Ausnahme. Die Rückgabe einer leeren Sammlung ist jedoch sinnvoll.
Ian
1
Nicht, wenn Sie einen einzelnen Artikel zurücksenden müssen (min / max / head / tail). Was null betrifft, hasse ich es (und bevorzuge Sprachen, die es nicht haben), aber wo eine Sprache es hat, muss man in der Lage sein, damit umzugehen und Code zu erstellen, der es austeilt. Abhängig von den lokalen Kodierungskonventionen kann dies angemessen sein.
itsbruce
Keines Ihrer Beispiele hat etwas mit einer leeren Eingabe zu tun. Es sind nur spezielle Fälle von Situationen, in denen die Antwort "nichts" sein könnte. Was wiederum die Frage des OP beantworten sollte, wie mit der leeren Sammlung umgegangen werden soll.
Djechlin
18

Wie immer kommt es darauf an.

Ist es wichtig, dass die Sammlung leer ist?
Der meiste Code für die Sammlung würde wahrscheinlich "nein" sagen. Eine Sammlung kann eine beliebige Anzahl von Elementen enthalten, einschließlich Null.

Wenn Sie eine Art Sammlung haben, in der es "ungültig" ist, keine Elemente darin zu haben, dann ist dies eine neue Anforderung, und Sie müssen entscheiden, was Sie dagegen tun möchten.

Leihen Sie sich eine Testlogik aus der Datenbankwelt aus: Prüfen Sie , ob keine , eine und zwei Elemente vorhanden sind. Dies ist für die wichtigsten Fälle geeignet (Herauslösen schlecht geformter innerer oder kartesischer Verbindungsbedingungen).

Phill W.
quelle
Und wenn es ungültig ist, keine Elemente in einer Auflistung zu haben, wäre das Argument im Idealfall nicht eine java.util.Collection, sondern eine benutzerdefinierte com.foo.util.NonEmptyCollectionKlasse, die diese Invariante konsistent beibehält und verhindert, dass Sie zunächst in einen ungültigen Zustand gelangen.
Andrzej Doyle
3
Diese Frage ist markiert mit [c #]
Nick Udell
@NickUdell unterstützt C # keine objektorientierte Programmierung oder das Konzept verschachtelter Namespaces? Bis.
John Dvorak
2
Es tut. Mein Kommentar war eine Klarstellung, da Andrzej verwirrt gewesen sein muss (warum sollten sie sich sonst bemühen, einen Namensraum für eine Sprache anzugeben, auf die sich diese Frage nicht bezieht?).
Nick Udell
-1 für die Betonung des "es hängt" mehr als das "mit ziemlicher Sicherheit ja". Kein Scherz - Falsches mitteilen schadet hier.
Djechlin
11

Akzeptieren Sie im Hinblick auf ein gutes Design so viele Variationen in Ihren Eingaben wie möglich. Ausnahmen sollten nur ausgelöst werden, wenn (bei der Verarbeitung werden nicht akzeptable Eingaben angezeigt ODER es treten unerwartete Fehler auf) UND das Programm daher nicht vorhersehbar fortgesetzt werden kann .

In diesem Fall ist zu erwarten, dass eine leere Auflistung angezeigt wird und Ihr Code damit umgehen muss (was er bereits tut). Es wäre eine Verletzung von allem, was gut ist, wenn Ihr Code hier eine Ausnahme auslösen würde. Dies wäre vergleichbar mit dem Multiplizieren von 0 mit 0 in der Mathematik. Es ist überflüssig, aber absolut notwendig, damit es so funktioniert, wie es funktioniert.

Nun zum Argument der Nullsammlung. In diesem Fall ist eine Nullsammlung ein Programmierfehler: Der Programmierer hat vergessen, eine Variable zuzuweisen. Dies ist ein Fall, in dem eine Ausnahme ausgelöst werden kann, da Sie diese nicht sinnvoll in eine Ausgabe verarbeiten können. Wenn Sie dies versuchen, tritt ein unerwartetes Verhalten auf. Dies wäre in der Mathematik gleichbedeutend mit einer Division durch Null - es ist völlig bedeutungslos.

theMayer
quelle
Ihre kühne Aussage ist ein äußerst schlechter Rat in voller Allgemeinheit. Ich denke, dass es hier stimmt, aber Sie müssen erklären, was an diesem Umstand besonders ist. (Es ist im Allgemeinen ein schlechter Rat, weil er stille Fehler fördert.)
Djechlin,
@AAA - Natürlich schreiben wir hier kein Buch über das Entwerfen von Software, aber ich denke, es ist überhaupt kein schlechter Rat, wenn Sie wirklich verstehen, was ich sage. Mein Punkt ist, dass Sie eine Ausnahme auslösen müssen, wenn eine schlechte Eingabe zu einer mehrdeutigen oder willkürlichen Ausgabe führt. In Fällen, in denen die Ausgabe vollständig vorhersehbar ist (wie hier der Fall), wäre das Auslösen einer Ausnahme willkürlich. Der Schlüssel ist, niemals willkürliche Entscheidungen in Ihrem Programm zu treffen, da dies die Ursache für unvorhersehbares Verhalten ist.
theMayer
Aber es ist dein erster Satz und der einzig hervorgehobene. Niemand versteht, was du sagst. (Ich versuche hier nicht, zu aggressiv zu sein. Wir müssen nur lernen, zu schreiben und zu kommunizieren, und ich tue, dass der Verlust an Präzision in einem wichtigen Punkt schädlich ist.)
djechlin
10

Die richtige Lösung ist viel schwieriger zu erkennen, wenn Sie Ihre Funktion nur isoliert betrachten. Betrachten Sie Ihre Funktion als Teil eines größeren Problems . Eine mögliche Lösung für dieses Beispiel sieht folgendermaßen aus (in Scala):

input.split("\\D")
.filterNot (_.isEmpty)
.map (_.toInt)
.filter (x => x >= 1000 && x <= 9999)

Zuerst teilen Sie die Zeichenfolge nach Nicht-Ziffern auf, filtern die leeren Zeichenfolgen heraus, konvertieren die Zeichenfolgen in Ganzzahlen und filtern dann, um nur die vierstelligen Zahlen beizubehalten. Ihre Funktion könnte die map (_.toInt)in der Pipeline sein.

Dieser Code ist ziemlich einfach, da jede Phase in der Pipeline nur eine leere Zeichenfolge oder eine leere Auflistung verarbeitet. Wenn Sie am Anfang eine leere Zeichenfolge eingeben, wird am Ende eine leere Liste ausgegeben. Sie müssen nicht nullnach jedem Anruf anhalten und nach einer Ausnahme suchen.

Dies setzt natürlich voraus, dass eine leere Ausgabeliste nicht mehr als eine Bedeutung hat. Wenn Sie zwischen einer leeren Ausgabe, die durch eine leere Eingabe verursacht wird, und einer durch die Transformation selbst verursachten Ausgabe unterscheiden müssen , ändert sich das grundlegend.

Karl Bielefeldt
quelle
+1 für extrem effektives Beispiel (es fehlen die anderen guten Antworten).
Djechlin
2

Bei dieser Frage handelt es sich eigentlich um Ausnahmen. Wenn Sie dies so betrachten und die leere Auflistung als Implementierungsdetail ignorieren, ist die Antwort einfach:

1) Eine Methode sollte eine Ausnahme auslösen, wenn sie nicht fortfahren kann: entweder die angegebene Aufgabe nicht ausführen oder den entsprechenden Wert zurückgeben.

2) Eine Methode sollte eine Ausnahme abfangen, wenn sie trotz des Fehlers fortfahren kann.

Daher sollte Ihre Hilfsmethode nicht "hilfreich" sein und eine Ausnahme auslösen, es sei denn, sie kann ihre Aufgabe nicht mit einer leeren Auflistung erledigen. Lassen Sie den Anrufer bestimmen, ob die Ergebnisse verarbeitet werden können.

Ob es eine leere Sammlung oder null zurückgibt, ist ein bisschen schwieriger, aber nicht viel: nullfähige Sammlungen sollten nach Möglichkeit vermieden werden. Der Zweck einer nullfähigen Auflistung besteht darin, (wie in SQL) anzugeben, dass Sie nicht über die Informationen verfügen. Eine Auflistung von untergeordneten Elementen kann beispielsweise null sein, wenn Sie nicht wissen, ob eine andere vorhanden ist, dies jedoch nicht wissen, dass sie es nicht tun. Aber wenn das aus irgendeinem Grund wichtig ist, ist es wahrscheinlich eine zusätzliche Variable wert, um es zu verfolgen.

jmoreno
quelle
1

Die Methode heißt TransformNodes. Im Falle einer leeren Sammlung als Eingabe ist es natürlich und intuitiv, eine leere Sammlung zurückzugewinnen, und dies ist mathematisch sinnvoll.

Wenn die Methode so benannt Maxund entworfen wurde, dass sie das maximale Element zurückgibt, wäre es natürlich, NoSuchElementExceptioneine leere Auflistung zu verwenden, da das Maximum von nichts keinen mathematischen Sinn ergibt.

Wenn die Methode so benannt JoinSqlColumnNamesund entworfen wurde, dass sie eine Zeichenfolge zurückgibt, bei der die Elemente durch ein Komma verbunden sind, um sie in SQL-Abfragen zu verwenden, wäre es sinnvoll, IllegalArgumentExceptioneine leere Auflistung zu verwenden, da der Aufrufer schließlich ohnehin einen SQL-Fehler erhalten würde, wenn er sie verwendet die Zeichenfolge in einer SQL-Abfrage direkt ohne weitere Überprüfungen, und anstatt auf eine zurückgegebene leere Zeichenfolge zu prüfen, hätte er stattdessen wirklich auf leere Auflistung prüfen müssen.

Hör auf, Monica weiter zu schaden
quelle
Maxvon nichts ist oft negative Unendlichkeit.
Djechlin
0

Lassen Sie uns einen Schritt zurücktreten und ein anderes Beispiel verwenden, das das arithmetische Mittel eines Array von Werten berechnet.

Wenn das Eingabearray leer (oder null) ist, können Sie die Anforderung des Aufrufers vernünftigerweise erfüllen? Nein. Welche Möglichkeiten haben Sie? Nun, Sie könnten:

  • präsentieren / zurückgeben / einen Fehler werfen. Verwenden Sie die Konvention Ihrer Codebasis für diese Fehlerklasse.
  • dokumentieren, dass ein Wert wie Null zurückgegeben wird
  • dokumentieren, dass ein bestimmter ungültiger Wert zurückgegeben wird (zB NaN)
  • dokumentieren, dass ein magischer Wert zurückgegeben wird (z. B. ein min oder max für den Typ oder ein hoffentlich indikativer Wert)
  • Deklarieren Sie, dass das Ergebnis nicht angegeben ist
  • erklären, dass die Aktion undefiniert ist
  • usw.

Ich sage, gib ihnen den Fehler, wenn sie dir eine ungültige Eingabe gegeben haben und die Anfrage nicht abgeschlossen werden kann. Ich meine einen schweren Fehler vom ersten Tag an, damit sie die Anforderungen Ihres Programms verstehen. Schließlich ist Ihre Funktion nicht in der Lage zu reagieren. Wenn die Operation fehlschlagen könnte (z. B. Kopieren einer Datei), sollte Ihre API einen Fehler melden, mit dem sie umgehen kann.

Auf diese Weise können Sie festlegen, wie Ihre Bibliothek fehlerhafte und möglicherweise fehlgeschlagene Anforderungen behandelt.

Es ist sehr wichtig, dass Ihr Code konsistent mit diesen Fehlerklassen umgeht.

In der nächsten Kategorie legen Sie fest, wie Ihre Bibliothek mit Unsinnanforderungen umgeht. Kommen wir zurück auf ein Beispiel ähnlich wie bei Ihnen - wir verwenden , um eine Funktion , die bestimmt , ob eine Datei auf einem Pfad vorhanden ist : bool FileExistsAtPath(String). Wie gehen Sie mit diesem Szenario um, wenn der Client eine leere Zeichenfolge übergibt? Wie wäre es mit einem leeren oder einem Null-Array, an das übergeben wird void SaveDocuments(Array<Document>)? Entscheiden Sie sich für Ihre Bibliothek / Codebasis und seien Sie konsistent. Ich betrachte diese Fälle zufällig als Fehler und verbiete Kunden, unsinnige Anfragen zu stellen, indem ich sie (über eine Behauptung) als Fehler markiere. Einige Leute werden sich dieser Idee / Aktion stark widersetzen. Ich finde diese Fehlererkennung sehr hilfreich. Es ist sehr gut, um Probleme in Programmen zu lokalisieren - mit einer guten Lokalisierung des betreffenden Programms. Programme sind viel klarer und korrekter (unter Berücksichtigung der Weiterentwicklung Ihrer Codebasis) und brennen keine Zyklen innerhalb von Funktionen, die nichts bewirken. Auf diese Weise wird der Code kleiner / sauberer, und die Überprüfungen werden im Allgemeinen an die Stellen verschoben, an denen das Problem möglicherweise auftritt.

Justin
quelle
6
Für Ihr letztes Beispiel ist es nicht die Aufgabe dieser Funktion, zu bestimmen, was Unsinn ist. Daher sollte eine leere Zeichenfolge false zurückgeben. Genau das ist der Ansatz, den File.Exists verfolgt .
theMayer
@ rmayer06 es ist seine Aufgabe. Die Funktion, auf die verwiesen wird, erlaubt null, leere Zeichenfolgen, sucht nach ungültigen Zeichen in der Zeichenfolge, schneidet Zeichenfolgen ab, muss möglicherweise Dateisystemaufrufe ausführen, muss möglicherweise die Umgebung abfragen usw. hohe Kosten, und sie verwischen definitiv die Grenzen der Korrektheit (IMO). Ich habe viele if (!FileExists(path)) { ...create it!!!... }Bugs gesehen - viele davon würden vor dem Commit gefangen werden, wenn die Linien der Korrektheit nicht verschwimmen würden.
Justin
2
Ich würde Ihnen zustimmen, wenn der Name der Funktion File.ThrowExceptionIfPathIsInvalid wäre, aber wer würde bei Verstand eine solche Funktion aufrufen?
theMayer
Ein Durchschnitt von 0 Elementen gibt aufgrund der Definition der Funktion bereits entweder NaN zurück oder löst eine durch Null teilende Ausnahme aus. Eine Datei mit einem Namen, der möglicherweise nicht existiert, existiert entweder nicht oder löst bereits einen Fehler aus. Es gibt keinen zwingenden Grund, diese Fälle speziell zu behandeln.
cHao
Man könnte sogar argumentieren, dass das gesamte Konzept, die Existenz einer Datei vor dem Lesen oder Schreiben zu überprüfen, ohnehin fehlerhaft ist. (Es gibt eine inhärente Race-Bedingung.) Gehen Sie einfach weiter und versuchen Sie, die Datei zum Lesen oder mit Nur-Erstellen-Einstellungen zu öffnen, wenn Sie schreiben möchten. Es schlägt bereits fehl, wenn der Dateiname ungültig oder nicht vorhanden ist (oder beim Schreiben).
cHao
-3

Als Faustregel gilt, dass eine Standardfunktion in der Lage sein sollte, die breiteste Liste von Eingaben zu akzeptieren und Feedback zu geben. Es gibt viele Beispiele, in denen Programmierer Funktionen auf eine Weise verwenden, die der Designer nicht geplant hatte. Aus diesem Grund glaube ich an die Funktion Sie sollten nicht nur leere Sammlungen, sondern eine Vielzahl von Eingabetypen akzeptieren und ordnungsgemäß Feedback geben können, auch wenn es sich um ein Fehlerobjekt handelt, das von einer beliebigen Operation an der Eingabe ausgeführt wurde.

Clement Mark-Aaba
quelle
Es ist absolut falsch, dass der Designer davon ausgeht, dass eine Sammlung immer übergeben wird, und diese Sammlung sofort durchläuft. Es muss überprüft werden, ob das empfangene Argument dem erwarteten Datentyp entspricht ...
Clement Mark-Aaba
3
"Große Auswahl an Eingabetypen" ist hier irrelevant. Die Frage ist mit c # markiert , einer stark typisierten Sprache. Das heißt, Compiler garantiert , dass die Eingabe eine Sammlung
gnat
Freundlicherweise Google "Faustregel", meine Antwort war eine allgemeine Warnung, dass Sie als Programmierer Platz für unvorhergesehene oder fehlerhafte Ereignisse schaffen, von denen eines fälschlicherweise als Funktionsargument übergeben werden kann ...
Clement Mark-Aaba
1
Dies ist entweder falsch oder tautologisch. writePaycheckToEmployeesollte keine negative Zahl als Eingabe akzeptieren ... aber wenn "Rückmeldung" bedeutet "tut etwas, was als nächstes passieren könnte", dann tut ja jede Funktion etwas, was sie als nächstes tut.
Djechlin