Frage 1:
Liegt es an der Rückgabe eines neuen StreamReader (Dateiname)? in der for-Schleife? oder die Tatsache, dass Sie in diesem Fall keine for-Schleife benötigen?
Der Streamreader hat nichts damit zu tun. Das Anti-Muster entsteht aufgrund eines klaren Absichtskonflikts zwischen dem foreach
und dem if
:
Was ist der Zweck der foreach
?
Ich gehe davon aus, dass Ihre Antwort ungefähr so lautet: "Ich möchte einen bestimmten Code wiederholt ausführen."
Wie viele Dateien werden voraussichtlich verarbeitet?
Da Sie nur einen bestimmten Dateinamen (einschließlich der Erweiterung) in einem bestimmten Ordner haben können, beweist dies, dass Ihr Code eine zutreffende Datei finden soll.
Dies wird auch dadurch bestätigt, dass Sie sofort einen Wert zurückgeben. Sie interessieren sich eigentlich nicht für ein zweites Match, selbst wenn es existieren würde.
Es gibt Situationen, in denen dies kein Anti-Muster ist.
- Wenn Sie auch in Unterverzeichnissen (
Directory.GetFiles(".", SearchOption.AllDirectories)
) suchen , ist es möglich, mehr als eine Datei mit demselben Dateinamen (einschließlich Erweiterung) zu finden.
- Wenn Sie nach partiellen Dateinamenübereinstimmungen suchen (z. B. jede Datei, deren Name mit beginnt
"Test_"
, oder jede "*.zip"
Datei.
Beachten Sie, dass Sie in beiden Fällen mehrere Übereinstimmungen verarbeiten müssen und daher nicht sofort einen Wert zurückgeben müssen.
Frage 2:
Um das zweite Beispiel zu korrigieren, würden Sie es ohne die if-Anweisung neu schreiben und stattdessen den StreamReader mit einem try-catch-Block umgeben. Wenn er eine FileNotFoundException auslöst, behandeln Sie ihn entsprechend im catch-Block?
Ausnahmen sind teuer. Sie sollten niemals anstelle einer ordnungsgemäßen Flusslogik verwendet werden. Ausnahmen sind, wie der Name schon sagt, außergewöhnliche Umstände.
Aus diesem Grund sollten Sie das nicht entfernen if
.
Gemäß dieser Antwort auf SoftwareEngineering.SE :
Im Allgemeinen ist die Verwendung von Ausnahmen für den Kontrollfluss ein Anti-Muster mit bemerkenswerten situations- und sprachspezifischen Hustenausnahmen.
Als kurze Zusammenfassung, warum es im Allgemeinen ein Anti-Muster ist:
- Ausnahmen sind im Wesentlichen ausgefeilte GOTO-Anweisungen
- Das Programmieren mit Ausnahmen führt daher dazu, dass Code schwieriger zu lesen und zu verstehen ist
- In den meisten Sprachen sind Kontrollstrukturen vorhanden, mit denen Sie Ihre Probleme ohne Ausnahmen lösen können
- Effizienzargumente sind für moderne Compiler eher umstritten, die tendenziell mit der Annahme optimieren, dass Ausnahmen nicht für den Kontrollfluss verwendet werden.
Lesen Sie die Diskussion in Wards Wiki, um weitere Informationen zu erhalten.
Ob Sie dies in einen Versuch / Fang einwickeln müssen, hängt stark von Ihrer Situation ab:
- Wie wahrscheinlich ist es, dass Sie auf eine Rennbedingung stoßen?
- Sind Sie tatsächlich in der Lage, mit dieser Situation umzugehen, oder möchten Sie, dass dieses Problem für den Benutzer auftritt, weil Sie nicht wissen, wie Sie damit umgehen sollen.
Nichts ist jemals eine Frage von "immer benutzen". Um meinen Standpunkt zu beweisen:
Separate Studien haben gezeigt, dass Sie weniger wahrscheinlich verletzt werden, wenn Sie einen Schutzhelm, eine Schutzbrille und kugelsichere Westen tragen.
Warum tragen wir nicht alle diese Sicherheitsausrüstung immer?
Die einfache Antwort ist, weil das Tragen Nachteile hat:
- Es kostet Geld
- Es macht Ihre Bewegung umständlicher
- Es kann sehr warm sein, es zu tragen.
Jetzt kommen wir voran: Es gibt Vor- und Nachteile . Mit anderen Worten, es ist nur dann sinnvoll, diese Ausrüstung zu tragen, wenn die Vorteile die Nachteile überwiegen .
- Bauarbeiter erleiden viel häufiger während ihrer Arbeit Verletzungen. Sie profitieren von einem Schutzhelm.
- Büroangestellte hingegen haben eine viel geringere Verletzungsgefahr. Schutzhelme sind es nicht wert.
- Ein SWAT-Teammitglied wird viel häufiger beschossen als ein Büroangestellter.
Sollten Sie den Anruf in einen Versuch / Fang einwickeln? Das hängt sehr davon ab, ob der Nutzen die Kosten für die Implementierung überwiegt.
Beachten Sie, dass andere möglicherweise argumentieren, dass es nur ein paar Tastenanschläge dauert, um es zu verpacken, daher sollte es offensichtlich getan werden. Aber das ist nicht das ganze Argument:
- Sie müssen entscheiden, was zu tun ist, sobald Sie die Ausnahme abfangen.
- Wenn in der gesamten Codebasis viele verschiedene Aufrufe an verschiedene Dateien erfolgen, bedeutet die Entscheidung, eine Datei in einen Versuch / Fang einzuschließen, im Allgemeinen, dass Sie alle diese Fälle umschließen müssen. Dies kann sich dramatisch auf den Aufwand auswirken, der für die Implementierung erforderlich ist.
- Es ist durchaus möglich, dass Sie absichtlich keine Ausnahme behandeln möchten .
- Beachten Sie, dass Ihre Anwendung die Ausnahme irgendwann behandeln muss, dies jedoch nicht unbedingt unmittelbar nach dem Auslösen der Ausnahme.
Sie haben also die Wahl. Hat dies einen Vorteil? Denken Sie, dass es die Anwendung verbessert, mehr als den Aufwand für die Implementierung?
Aktualisieren - Von einem Kommentar, den ich auf die andere Antwort geschrieben habe, da ich denke, dass dies auch für Sie eine relevante Überlegung ist:
Es hängt sehr stark vom umgebenden Kontext ab.
- Wenn dem Öffnen des Streamreaders vorausgegangen wird
if(!File.Exists) File.Create()
, ist das Fehlen der Datei beim Öffnen des Streamreader in der Tat außergewöhnlich .
- Wenn der Dateiname aus einer Liste vorhandener Dateien ausgewählt wurde, ist sein plötzliches Fehlen erneut außergewöhnlich .
- Wenn Sie mit einer Zeichenfolge arbeiten, die Sie noch nicht anhand des Verzeichnisses getestet haben; dann ist das Fehlen der Datei ein vollkommen logisches Ergebnis und daher keine Ausnahme .