Hi Leute,
ich habe ein grundlegendes Designproblem. Und zwar arbeite ich sehr gerne mit Try und Catch, da es so sehr leicht ist Fehler abzufangen. Aber Try und Catch ist meiner Meinung nach sehr sehr langsam. Darum sollte man (denke ich) alle Fehler die man ohne Try und Catch abfangen kann, vorher schon abfangen und als Rückgabewert einer Funktion bool wählen und True oder False zurückgeben, anstatt eine Exception zu werfen.
Dabei ergibt sich aber dass Designproblem (vl ist es ja gar kein Problem und so genau richtig), dass man nun in jeder Klasse einen string braucht indem die Errormessage steht.
zB:
public class ConfigurationHandler{
private string m_Error;
public string Error{
get{ return this.m_Error; }
}
public bool writeConfiguration(string Path, object Configuration){
try{
using(TextWriter oWriter = new StreamWriter(Path)){
XmlSerializer oSerial = new XmlSerializer(Configuration.GetType());
oSerial.Serialize(oWriter, Configuration);
return true;
}
}
catch(System.Exception e){
this.m_Error = e.Message;
return false;
}
}
}
//Aufruf
XMLConfiguration.ConfigurationHandler x = new XMLConfiguration.ConfigurationHandler();
if(!x.writeConfiguration("fail", null)){
Console.WriteLine(x.Error);
}
So, was mich wie gesagt stört, ist dass in jeder Klasse nun ein Error string vorhanden sein muss, worin der Exception-Fehler gespeichert wird.
Da gibt es doch sicherlich bessere Designansätze....
lg
Bakunin
Hallo Bakunin,
Da gibt es doch sicherlich bessere Designansätze....
ja, Exceptions zu verwenden. Jede Abweichtung davon ist eine Extrawurst, die zu nichts anderem kompatibel ist. Und da du es (vermutlich) nicht schaffen wirst, die Welt von deinem Designansatz zu überzeugen, verwende den Standard: Excpetions.
herbivore
Also lieber Exceptions werfen...
na dann, tu ich sowieso lieber 😉
/edit
Und als Rückgabetyp in dem Fall void? Weil wenn eine Exception geworfen wird, dann verabschiedet man sich aus der Funktion oder?
Vielen Dank
Also ich hoffe ich habe dich richtig verstanden.
Hier mein aktualisierter Code:
public void writeConfiguration(string Path, object Configuration){
try{
using(TextWriter oWriter = new StreamWriter(Path)){
XmlSerializer oSerial = new XmlSerializer(Configuration.GetType());
oSerial.Serialize(oWriter, Configuration);
}
}
catch(System.Exception e){
throw e;
}
}
//Aufruf
try{
this.oCHandler.writeConfiguration("/tmp/myconfig.xml", oConfig);
}
catch(System.Exception e){
//Errorhandling
}
Hallo Bakunin,
du kannst und solltest es noch kürzer machen, indem du das try/catch in writeConfiguration weglässt. Das ist ja u.a. das nützliche an Exceptions, dass man sie nur da ins Spiel bringen muss, wo man sie behandeln will. Dein Code mit dem "rethrow" hat zudem den Nachteil, dass man nicht mehr sieht, wo die Exception unrsprünglich entstanden ist. Stattdessen wird als Ursprungsort die Zeile von deinem throw e eingetragen.
herbivore
Original von Bakunin
catch(System.Exception e){ throw e; Nur so am Rande: Statt throw e; reicht auch ein einfaches throw (dann wird die letzte gecatchte Exception wieder geworfen.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Ah ok, daran habe ich gar nicht gedacht. Vielen Dank
Und danke für den Tipp Programmierhans!
Bakunin
Ein "Rethrow" (also ein throw ohne Parameter) macht nur in den wenigsten Fällen Sinn sondern erhöht nur die Laufzeit des Codes (es treten ja 2 Exceptions auf).... Einzig Sinn macht es wenn die erste catchende Komponente noch was tun muss (z.B: den Fehler loggen (sprich Low-Level-Log) bevor die Exception dem Aufrufer um die Ohren gehauen wird).
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Nachtrag: Die Verwendung von Execeptions im Code verlangsamt die Ausführungzeit überhaupt nicht. Nur das Fangen von geworfenen Exceptions (gerade der ersten wegen JIT) ist im Vergleich zu einem Returncodes tatsächlich deutlich langsamer. Da aber Exceptions wirklich als "Ausnahmen" verwendet werden sollten, ist das Performance-Argument nur in den allerseltensten Fällen maßgebend.
Original von svenson
Nur das Fangen von geworfenen Exceptions (gerade der ersten wegen JIT) ist im Vergleich zu einem Returncodes tatsächlich deutlich langsamer.
Und genau dies hat er hier unnötigerweise gemacht... es wurde eine Exception gefangen um diese dann wieder zu werfen.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Das macht allerdings nur Sinn, wenn man die Exception loggen möchte, oder was weiss ich damit anstellen.
Original von svenson
Das macht allerdings nur Sinn, wenn man die Exception loggen möchte, oder was weiss ich damit anstellen.
Genau dies habe ich vorher ja beschrieben (wobei Du meinen Zwischenpost vermutlich gar nicht gesehen hast, da sich unsere Posts überschnitten haben)
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hallo zusammen,
wollte noch anmerken, dass jeder "rethrow", egal ob mit oder ohne Parameter, zu dem von mir oben beschriebenen Effekt des "verfälschten" Ursprungs führt.
herbivore
Hierzu würde ich auch noch gerne anmerken:
Ich denke ein "rethrow" macht auch Sinn, wenn man z.B. eine Klasse programmiert die mehrfach verwendet wird. Es ist so möglich, dass die "höheren" Prozeduren, Subs bzw. Voids die Exception behandeln. Je nachdem kann dann der Programmierer der Funktion damit weiter Arbeiten. (Er kann dann einschätzen den Grad des Fehlers und muss dann nicht zwangsweise eine Message anzeigen lassen.)