Es wird davon abgeraten, einfach zu fangen System.Exception
. Stattdessen sollten nur die "bekannten" Ausnahmen abgefangen werden.
Dies führt manchmal zu unnötigem sich wiederholendem Code, zum Beispiel:
try
{
WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
WebId = Guid.Empty;
}
catch (OverflowException)
{
WebId = Guid.Empty;
}
Ich frage mich: Gibt es eine Möglichkeit, beide Ausnahmen abzufangen und den WebId = Guid.Empty
Anruf nur einmal anzurufen?
Das gegebene Beispiel ist ziemlich einfach, da es nur ein ist GUID
. Stellen Sie sich jedoch Code vor, in dem Sie ein Objekt mehrmals ändern. Wenn eine der Manipulationen erwartungsgemäß fehlschlägt, möchten Sie das Objekt "zurücksetzen" object
. Wenn es jedoch eine unerwartete Ausnahme gibt, möchte ich diese trotzdem höher werfen.
c#
.net
exception
exception-handling
Michael Stum
quelle
quelle
AggregateException
: Auslösen einer AggregateException in meinem eigenen CodeAntworten:
Fangen
System.Exception
und schalten Sie die Typen einquelle
BEARBEITEN: Ich stimme anderen zu, die sagen, dass Ausnahmefilter ab C # 6.0 jetzt ein perfekter Weg sind:
catch (Exception ex) when (ex is ... || ex is ... )
Abgesehen davon, dass ich das einzeilige Layout immer noch hasse und den Code persönlich wie folgt auslegen würde. Ich denke, dies ist ebenso funktional wie ästhetisch, da ich glaube, dass es das Verständnis verbessert. Einige mögen anderer Meinung sein:
ORIGINAL:
Ich weiß, ich bin ein bisschen zu spät zur Party hier, aber heiliger Rauch ...
Auf den Punkt gebracht, dupliziert diese Art eine frühere Antwort. Wenn Sie jedoch wirklich eine gemeinsame Aktion für mehrere Ausnahmetypen ausführen und das Ganze im Rahmen der einen Methode ordentlich und ordentlich halten möchten, verwenden Sie doch einfach ein Lambda / Closure / Inline-Funktion, um Folgendes zu tun? Ich meine, die Chancen stehen gut, dass Sie am Ende erkennen, dass Sie diesen Verschluss nur zu einer separaten Methode machen möchten, die Sie überall anwenden können. Aber dann wird es super einfach sein, dies zu tun, ohne den Rest des Codes strukturell zu ändern. Recht?
Ich kann nicht anders, als mich zu fragen ( Warnung: ein wenig Ironie / Sarkasmus voraus), warum um alles in der Welt all diese Anstrengungen unternommen werden, um im Grunde nur Folgendes zu ersetzen:
... mit einer verrückten Variation dieses nächsten Codegeruchs, meine ich zum Beispiel, nur um so zu tun, als würden Sie ein paar Tastenanschläge speichern.
Weil es sicherlich nicht automatisch besser lesbar ist.
Zugegeben, ich habe die drei identischen Instanzen
/* write to a log, whatever... */ return;
aus dem ersten Beispiel herausgelassen.Aber das ist irgendwie mein Punkt. Sie haben schon von Funktionen / Methoden gehört, oder? Ernsthaft. Schreiben Sie eine gemeinsame
ErrorHandler
Funktion und rufen Sie sie von jedem catch-Block aus auf.Wenn Sie mich fragen, ist das zweite Beispiel (mit den Schlüsselwörtern
if
undis
) sowohl deutlich weniger lesbar als auch gleichzeitig während der Wartungsphase Ihres Projekts wesentlich fehleranfälliger.Die Wartungsphase für alle, die noch relativ neu in der Programmierung sind, wird 98,7% oder mehr der gesamten Lebensdauer Ihres Projekts ausmachen, und der arme Trottel, der die Wartung durchführt, wird mit ziemlicher Sicherheit jemand anderes als Sie sein. Und es besteht eine sehr gute Chance, dass sie 50% ihrer Zeit damit verbringen, Ihren Namen zu verfluchen.
Und natürlich bellt FxCop Sie an, und deshalb müssen Sie Ihrem Code auch ein Attribut hinzufügen, das genau mit dem laufenden Programm zu tun hat und nur dazu dient, FxCop anzuweisen, ein Problem zu ignorieren, das in 99,9% der Fälle vollständig auftritt richtig in der Kennzeichnung. Tut mir leid, ich könnte mich irren, aber wird dieses Attribut "Ignorieren" nicht tatsächlich in Ihre App kompiliert?
Würde
if
es besser lesbar sein , den gesamten Test in eine Zeile zu setzen? Das glaube ich nicht. Ich meine, ich hatte vor langer Zeit einen anderen Programmierer, der vehement argumentierte, dass mehr Code in eine Zeile "schneller laufen" würde. Aber natürlich war er total verrückt. Der Versuch, ihm (mit ernstem Gesicht - was eine Herausforderung war) zu erklären, wie der Interpreter oder Compiler diese lange Zeile in diskrete Anweisungen mit einer Anweisung pro Zeile zerlegen würde - im Wesentlichen identisch mit dem Ergebnis, wenn er fortgefahren wäre und Ich habe nur den Code lesbar gemacht, anstatt zu versuchen, den Compiler zu überlisten - hatte keinerlei Auswirkungen auf ihn. Aber ich schweife ab.Wie viel weniger lesbar wird dies, wenn Sie in ein oder zwei Monaten drei weitere Ausnahmetypen hinzufügen? (Antwort: es wird viel weniger lesbar).
Einer der wichtigsten Punkte ist, dass der größte Teil der Formatierung des Textquellcodes, den wir uns jeden Tag ansehen, darin besteht, anderen Menschen wirklich, wirklich klar zu machen, was tatsächlich passiert, wenn der Code ausgeführt wird. Weil der Compiler den Quellcode in etwas völlig anderes verwandelt und sich nicht weniger um Ihren Code-Formatierungsstil kümmert. All-on-One-Line ist also auch total beschissen.
Ich sage nur ...
quelle
Exception
s fangen und den Typ überprüfen. Ich dachte, es würde den Code bereinigen, aber irgendetwas brachte mich dazu, auf die Frage zurückzukommen, und ich las tatsächlich die anderen Antworten auf die Frage. Ich habe eine Weile daran gekaut, aber ich muss dir zustimmen. Es ist besser lesbar und wartbar, eine Funktion zum Austrocknen Ihres Codes zu verwenden, als alles abzufangen, den Typ mit einer Liste zu vergleichen, Code zu verpacken und zu werfen. Vielen Dank, dass Sie zu spät gekommen sind und eine alternative und vernünftige Option (IMO) angeboten haben. +1.throw;
. Sie müssten diese Codezeile in jedem Catch-Block wiederholen (offensichtlich nicht das Ende der Welt, aber erwähnenswert, da es sich um Code handelt, der wiederholt werden müsste).throw();
Anweisung in jedem Catch-Block ist ein geringer Preis, IMO, und lässt Sie dennoch in der Lage, bei Bedarf zusätzliche ausnahmetypspezifische Bereinigungen durchzuführen.Func<Exception, MyEnumType>
stattAction<Exception>
. Das istFunc<T, Result>
, mitResult
wobei der Rückgabetyp.Wie andere bereits betont haben, können Sie eine
if
Anweisung in Ihrem catch-Block haben, um festzustellen, was los ist. C # 6 unterstützt Ausnahmefilter, daher funktioniert Folgendes:Die
MyFilter
Methode könnte dann ungefähr so aussehen:Alternativ kann dies alles inline erfolgen (die rechte Seite der when-Anweisung muss nur ein boolescher Ausdruck sein).
Dies unterscheidet sich von der Verwendung einer
if
Anweisung innerhalb descatch
Blocks. Durch die Verwendung von Ausnahmefiltern wird der Stapel nicht abgewickelt.Sie können Visual Studio 2015 herunterladen , um dies zu überprüfen.
Wenn Sie Visual Studio 2013 weiterhin verwenden möchten, können Sie das folgende Nuget-Paket installieren:
Zum Zeitpunkt des Schreibens umfasst dies die Unterstützung für C # 6.
quelle
Leider nicht in C #, da Sie dafür einen Ausnahmefilter benötigen und C # diese Funktion von MSIL nicht verfügbar macht. VB.NET verfügt jedoch über diese Funktion, z
Sie können eine anonyme Funktion verwenden, um Ihren Fehlercode zu kapseln und ihn dann in den folgenden Catch-Blöcken aufzurufen:
quelle
throw e;
zerstört Stacktrace und Callstack,throw;
zerstört "nur" Callstack (macht Crash-Dumps unbrauchbar!) Ein sehr guter Grund, beides nicht zu verwenden, wenn es vermieden werden kann!Der Vollständigkeit halber kann der Code seit .NET 4.0 wie folgt umgeschrieben werden:
TryParse löst niemals Ausnahmen aus und gibt false zurück, wenn das Format falsch ist, und setzt WebId auf
Guid.Empty
.Seit C # 7 können Sie vermeiden, eine Variable in eine separate Zeile einzufügen:
Sie können auch Methoden zum Parsen von zurückgegebenen Tupeln erstellen, die in .NET Framework ab Version 4.6 noch nicht verfügbar sind:
Und benutze sie so:
Das nächste nutzlose Update dieser nutzlosen Antwort erfolgt, wenn die Dekonstruktion von Out-Parametern in C # 12 implementiert ist. :)
quelle
Guid.TryParse
nie zurückGuid.Empty
. Wenn die Zeichenfolge ein falsches Format hat, setzt sie denresult
Ausgabeparameter aufGuid.Empty
, gibt jedoch zurückfalse
. Ich erwähne es, weil ich Code gesehen habe, der Dinge im Stil von tutGuid.TryParse(s, out guid); if (guid == Guid.Empty) { /* handle invalid s */ }
, was normalerweise falsch ist, wenn ess
sich um die Zeichenfolgendarstellung von handeln könnteGuid.Empty
.if( Guid.TryParse(s, out guid){ /* success! */ } else { /* handle invalid s */ }
, was keine Mehrdeutigkeit hinterlässt wie das fehlerhafte Beispiel, bei dem der Eingabewert tatsächlich die Zeichenfolgendarstellung eines Guid sein könnte.Ausnahmefilter sind jetzt in c # 6+ verfügbar. Du kannst tun
In C # 7.0+ können Sie dies auch mit dem Mustervergleich kombinieren
quelle
Wenn Sie Ihre Anwendung auf C # 6 aktualisieren können, haben Sie Glück. Die neue C # -Version hat Ausnahmefilter implementiert. Sie können also Folgendes schreiben:
Einige Leute denken, dieser Code ist der gleiche wie
Aber es ist nicht. Tatsächlich ist dies die einzige neue Funktion in C # 6, die in früheren Versionen nicht emuliert werden kann. Erstens bedeutet ein erneuter Wurf mehr Aufwand als das Überspringen des Fangs. Zweitens ist es nicht semantisch äquivalent. Die neue Funktion behält den Stapel beim Debuggen Ihres Codes bei. Ohne diese Funktion ist der Absturzspeicherauszug weniger nützlich oder sogar nutzlos.
Eine Diskussion hierzu finden Sie auf CodePlex . Und ein Beispiel, das den Unterschied zeigt .
quelle
Wenn Sie nicht über eine verwenden möchten
if
Anweisung innerhalb dercatch
Bereiche, inC# 6.0
denen Sie verwenden könnenException Filters
Syntax , die bereits von der CLR in Vorschauen Versionen unterstützt wurde , aber gab es nur inVB.NET
/MSIL
:Dieser Code fängt den
Exception
einzigen ab, wenn es sich um einInvalidDataException
oder handeltArgumentNullException
.Tatsächlich können Sie grundsätzlich jede Bedingung in diese
when
Klausel einfügen:Beachten Sie, dass im Gegensatz zu einer
if
Anweisung imcatch
Gültigkeitsbereich des BereichsException Filters
nicht geworfen werdenExceptions
kann. Wenn diestrue
dercatch
Fall ist oder wenn die Bedingung nicht erfüllt ist , wird stattdessen die nächste Bedingung ausgewertet:Wenn es mehr als eine gibt, wird
true
Exception Filter
die erste akzeptiert:Und wie Sie im
MSIL
Code sehen können, wird der Code nicht inif
Anweisungen übersetzt , sondern inFilters
undExceptions
kann nicht aus den mitFilter 1
und gekennzeichneten BereichenFilter 2
geworfenException
werden, aber der Filter, der den Code auslöst , schlägt stattdessen fehl, auch der letzte Vergleichswert, der vor demendfilter
Befehl auf den Stapel verschoben wurde bestimmt den Erfolg / Misserfolg des Filters (Catch 1
XORCatch 2
wird entsprechend ausgeführt):Hat auch speziell
Guid
dieGuid.TryParse
Methode.quelle
Mit C # 7 kann die Antwort von Michael Stum verbessert werden, während die Lesbarkeit einer switch-Anweisung erhalten bleibt :
Und mit C # 8 als Schalterausdruck:
quelle
when
ist weitaus eleganter / angemessener als ein Schalter.catch
Block, oder Sie müssen ihn trotzdem umwandeln. Nach meiner Erfahrung ist einthrow;
in Ihremcatch
Block wahrscheinlich ein Codegeruch.Die akzeptierte Antwort scheint akzeptabel zu sein, außer dass CodeAnalysis / FxCop sich über die Tatsache beschwert, dass ein allgemeiner Ausnahmetyp abgefangen wird.
Es scheint auch, dass der Operator "is" die Leistung geringfügig beeinträchtigen könnte.
CA1800: Cast nicht unnötig sagt, dass "stattdessen das Ergebnis des Operators 'as' getestet werden soll", aber wenn Sie dies tun, schreiben Sie mehr Code, als wenn Sie jede Ausnahme einzeln abfangen.
Jedenfalls würde ich Folgendes tun:
quelle
is
Operators einen leichten negativen Einfluss auf die Leistung hat, ist es auch wahr, dass ein Ausnahmebehandler nicht der Ort ist, an dem man sich übermäßig Gedanken über die Optimierung der Leistung machen muss. Wenn Ihre App so viel Zeit in Ausnahmebehandlungsroutinen verbringt, dass die Leistungsoptimierung dort einen echten Unterschied in der App-Leistung bewirken würde, gibt es andere Codeprobleme, die Sie sich genauer ansehen sollten. Trotzdem gefällt mir diese Lösung immer noch nicht, weil Sie den Stack-Trace verlieren und die Bereinigung kontextuell aus der catch-Anweisung entfernt wird.is
Bediener beeinträchtigt die Leistung nur, wenn Sie später eineas
Operation ausführen (daher wird die Regel unnötig qualifiziert ). Wenn Sie nur die Besetzung testen, ohne die Besetzung tatsächlich durchführen zu müssen, ist deris
Operator genau das, was Sie verwenden möchten.In C # 6 wird empfohlen, Ausnahmefilter zu verwenden. Hier ein Beispiel:
quelle
Dies ist eine Variante von Matts Antwort (ich denke, das ist ein bisschen sauberer) ... benutze eine Methode:
Alle anderen Ausnahmen werden ausgelöst und der Code
WebId = Guid.Empty;
wird nicht getroffen. Wenn Sie nicht möchten, dass andere Ausnahmen Ihr Programm zum Absturz bringen, fügen Sie dies NACH den beiden anderen Fängen hinzu:quelle
WebId = Guid.Emtpy
, wenn keine Ausnahme ausgelöst wurde.return
meiner Antwort jedoch ein hinzugefügt . Danke für die Eingabe.Joseph Daigles Antwort ist eine gute Lösung, aber ich fand die folgende Struktur etwas aufgeräumter und weniger fehleranfällig.
Das Invertieren des Ausdrucks bietet einige Vorteile:
Es kann sogar zu einer einzigen Zeile komprimiert werden (obwohl nicht sehr hübsch)
Bearbeiten: Die Ausnahmefilterung in C # 6.0 macht die Syntax etwas sauberer und bietet gegenüber jeder aktuellen Lösung eine Reihe weiterer Vorteile . (vor allem den Stapel unversehrt lassen)
So würde das gleiche Problem mit der C # 6.0-Syntax aussehen:
quelle
return
, obwohl das Umkehren des Zustands auch etwas besser ist.@ Michael
Leicht überarbeitete Version Ihres Codes:
String-Vergleiche sind hässlich und langsam.
quelle
throw new FormatException();
mitthrow new NewlyDerivedFromFormatException();
ohne Code zu brechen , die Bibliothek verwendet wird , und es wird Fälle mit Ausnahme gilt für alle Ausnahme wahr Umgang mit dem jemand verwendete==
anstelle vonis
(oder einfachcatch (FormatException)
).Wie wäre es mit
quelle
quelle
Vorsicht und Warnung: Noch ein anderer, funktionaler Stil.
Was in dem Link enthalten ist, beantwortet Ihre Frage nicht direkt, aber es ist trivial, sie so zu erweitern, dass sie aussieht:
(Grundsätzlich eine weitere leere
Catch
Überladung bereitstellen, die sich selbst zurückgibt)Die größere Frage dazu ist warum . Ich denke nicht, dass die Kosten den Gewinn hier überwiegen :)
quelle
Update 15.12.2015: Siehe https://stackoverflow.com/a/22864936/1718702 C # 6 finden . Es ist sauberer und jetzt Standard in der Sprache.
Ausgerichtet für Menschen, die eine elegantere Lösung suchenIch bin , um einmal zu fangen und Ausnahmen zu filtern. Ich verwende eine Erweiterungsmethode, wie unten gezeigt.
Ich hatte diese Erweiterung bereits in meiner Bibliothek, die ursprünglich für andere Zwecke geschrieben wurde, aber sie funktionierte perfekt
type
, um Ausnahmen zu überprüfen. Außerdem sieht es imho sauberer aus als eine Reihe von||
Aussagen. Im Gegensatz zur akzeptierten Antwort bevorzuge ich auch die explizite Ausnahmebehandlung, sodass ich einex is ...
unerwünschtes Verhalten hatte, da abgeleitete Klassen den übergeordneten Typen zugewiesen werden können.Verwendungszweck
IsAnyOf.cs-Erweiterung (Abhängigkeiten siehe Beispiel für die vollständige Fehlerbehandlung)
Beispiel für die vollständige Fehlerbehandlung (Kopieren, Einfügen in neue Konsolen-App)
Zwei Beispiel-NUnit-Unit-Tests
Das Übereinstimmungsverhalten für
Exception
Typen ist genau (dh ein Kind ist KEINE Übereinstimmung für einen seiner übergeordneten Typen).quelle
when
wie jede Version von nur die Semantik von C # 6 annähertcatch (Exception ex) {if (...) {/*handle*/} throw;}
. Der wahre Wert vonwhen
ist, dass der Filter ausgeführt wird, bevor die Ausnahme abgefangen wird , wodurch die Kosten- / Stapelbeschädigung eines erneuten Auslösens vermieden wird. Es nutzt eine CLR-Funktion, auf die bisher nur VB und MSIL zugreifen konnten.IsAnyOf
Methode kann einfach umgeschrieben werdenp_comparisons.Contains(p_parameter)
Da ich das Gefühl hatte, dass diese Antworten nur die Oberfläche berührten, versuchte ich etwas tiefer zu graben.
Was wir also wirklich tun möchten, ist etwas, das nicht kompiliert werden kann, sagen wir:
Der Grund, warum wir dies wollen, ist, dass wir nicht möchten, dass der Ausnahmebehandler Dinge abfängt, die wir später im Prozess benötigen. Sicher, wir können eine Ausnahme abfangen und mit einem "Wenn" prüfen, was zu tun ist, aber seien wir ehrlich, das wollen wir nicht wirklich. (FxCop, Debugger-Probleme, Hässlichkeit)
Warum wird dieser Code nicht kompiliert - und wie können wir ihn so hacken, dass er es tut?
Wenn wir uns den Code ansehen, möchten wir den Anruf wirklich weiterleiten. Gemäß der MS-Partition II funktionieren IL-Ausnahmebehandlungsblöcke jedoch nicht so, was in diesem Fall sinnvoll ist, da dies bedeuten würde, dass das 'Ausnahme'-Objekt unterschiedliche Typen haben kann.
Oder um es in Code zu schreiben, bitten wir den Compiler, so etwas zu tun (nun, es ist nicht ganz richtig, aber es ist das nächstmögliche, was ich denke):
Der Grund, warum dies nicht kompiliert werden kann, liegt auf der Hand: Welchen Typ und Wert hätte das Objekt '$ exception' (die hier in den Variablen 'e' gespeichert sind)? Der Compiler soll damit umgehen, indem er feststellt, dass der gemeinsame Basistyp beider Ausnahmen "Ausnahme" ist. Verwenden Sie diesen Typ für eine Variable, die beide Ausnahmen enthält, und behandeln Sie dann nur die beiden abgefangenen Ausnahmen. Die Art und Weise, wie dies in IL implementiert wird, ist als 'Filter', der in VB.Net verfügbar ist.
Damit es in C # funktioniert, benötigen wir eine temporäre Variable mit dem richtigen Basistyp 'Exception'. Um den Codefluss zu steuern, können wir einige Zweige hinzufügen. Hier geht:
Die offensichtlichen Nachteile dafür sind, dass wir nicht richtig zurückwerfen können und - seien wir ehrlich - dass es eine ziemlich hässliche Lösung ist. Die Hässlichkeit kann ein wenig behoben werden, indem eine Verzweigungseliminierung durchgeführt wird, wodurch die Lösung etwas besser wird:
Das lässt nur den "Neuwurf". Damit dies funktioniert, müssen wir in der Lage sein, die Behandlung innerhalb des 'catch'-Blocks durchzuführen - und die einzige Möglichkeit, dies zu erreichen, ist ein abfangendes' Exception'-Objekt.
An dieser Stelle können wir eine separate Funktion hinzufügen, die die verschiedenen Arten von Ausnahmen mithilfe der Überlastungsauflösung oder zur Behandlung der Ausnahme behandelt. Beide haben Nachteile. Hier ist der Weg, um dies mit einer Hilfsfunktion zu tun:
Die andere Lösung besteht darin, das Exception-Objekt abzufangen und entsprechend zu behandeln. Die wörtlichste Übersetzung hierfür, basierend auf dem obigen Kontext, lautet:
Also zum Schluss:
quelle
Dies ist ein klassisches Problem, mit dem jeder C # -Entwickler irgendwann konfrontiert ist.
Lassen Sie mich Ihre Frage in zwei Fragen aufteilen. Der Erste,
Kann ich mehrere Ausnahmen gleichzeitig abfangen?
Kurz gesagt, nein.
Was zur nächsten Frage führt:
Wie vermeide ich das Schreiben von doppeltem Code, da ich nicht mehrere Ausnahmetypen im selben catch () -Block abfangen kann?
In Anbetracht Ihrer spezifischen Stichprobe, bei der der Fallback-Wert günstig zu konstruieren ist, möchte ich die folgenden Schritte ausführen:
Der Code sieht also so aus:
Wenn eine Ausnahme ausgelöst wird, wird WebId niemals auf den halb konstruierten Wert gesetzt und bleibt Guid.Empty.
Wenn das Erstellen des Fallback-Werts teuer und das Zurücksetzen eines Werts viel billiger ist, würde ich den Rücksetzcode in eine eigene Funktion verschieben:
quelle
Sie wiederholen also viel Code in jedem Ausnahmeschalter? Klingt so, als wäre das Extrahieren einer Methode eine gute Idee, nicht wahr?
Ihr Code läuft also auf Folgendes hinaus:
Ich frage mich, warum niemand diese Codeduplizierung bemerkt hat.
Ab C # 6 haben Sie außerdem die Ausnahmefilter, wie bereits von anderen erwähnt. So können Sie den obigen Code folgendermaßen ändern:
quelle
Wollte meine kurze Antwort zu diesem bereits langen Thread hinzufügen. Was nicht erwähnt wurde, ist die Rangfolge der catch-Anweisungen. Insbesondere müssen Sie den Umfang jeder Art von Ausnahme kennen, die Sie abfangen möchten.
Wenn Sie beispielsweise eine "catch-all" -Ausnahme als Ausnahme verwenden , geht sie allen anderen catch-Anweisungen voraus, und Sie erhalten offensichtlich Compilerfehler. Wenn Sie jedoch die Reihenfolge umkehren, können Sie Ihre catch-Anweisungen verketten (ein bisschen ein Anti-Pattern, denke ich ) Sie können den Catch-All- Ausnahmetyp unten einfügen. Dadurch werden alle Ausnahmen erfasst, die in Ihrem try..catch-Block nicht berücksichtigt wurden:
Ich empfehle den Leuten dringend, dieses MSDN-Dokument zu lesen:
Ausnahmehierarchie
quelle
Versuchen Sie vielleicht, Ihren Code einfach zu halten, z. B. den allgemeinen Code in eine Methode einzufügen, wie Sie es in jedem anderen Teil des Codes tun würden, der nicht in einer catch-Klausel enthalten ist?
Z.B:
Wie ich es machen würde, wenn ich versuche, das Einfache zu finden, ist ein schönes Muster
quelle
Beachten Sie, dass ich einen Weg gefunden habe, dies zu tun, aber dies sieht eher nach Material für The Daily WTF aus :
quelle
Erwähnenswert ist hier. Sie können auf mehrere Kombinationen reagieren (Ausnahmefehler und Ausnahmemeldung).
Beim Versuch, ein Steuerobjekt in ein Datagrid mit Inhalten wie TextBox, TextBlock oder CheckBox umzuwandeln, ist ein Anwendungsszenario aufgetreten. In diesem Fall war die zurückgegebene Ausnahme dieselbe, aber die Nachricht variierte.
quelle
Ich möchte die kürzeste Antwort vorschlagen (ein weiterer funktionaler Stil ):
Dazu müssen Sie mehrere "Catch" -Methodenüberladungen erstellen, ähnlich wie bei System.Action:
und so weiter so viele wie du willst. Sie müssen es jedoch einmal ausführen und können es in all Ihren Projekten verwenden (oder wenn Sie ein Nuget-Paket erstellt haben, können wir es auch verwenden).
Und CatchMany-Implementierung:
ps Ich habe keine Nullprüfungen für die Einfachheit des Codes durchgeführt. Erwägen Sie, Parameterüberprüfungen hinzuzufügen.
ps2 Wenn Sie einen Wert aus dem catch zurückgeben möchten, müssen Sie dieselben Catch-Methoden ausführen, jedoch mit return und Func anstelle von Action in Parametern.
quelle
Rufen Sie einfach den Versuch an und fangen Sie zweimal.
So einfach ist das !!
quelle
In c # 6.0 sind Ausnahmefilter Verbesserungen für die Ausnahmebehandlung
quelle
catch (HttpException e) when e.GetHttpCode() == 400 { WriteLine("Bad Request"; }