Laden...

try/catch: Programmierstil

Letzter Beitrag vor 15 Jahren 61 Posts 39.751 Views

@Winsharp93

Was aber dennoch der Fall zu sein scheint: Wenn eine Exception während des Debuggens bei dir nicht auftritt, weil z.B. eine Datei vorhanden ist, dann wird diese nie berücksichtigt, oder?

Auch wenn es bis dato nicht auftrat will ich nicht auschliessen, daß ich mal einen Fehler übersehe. Datei ist ein schlechtes Beispiel - da brauche ich keine allgemeinen try...catch und achte auf mögliche Fehler beim Laden.
Nur was hat das mit der Ausgangsfrage zu tun? Du würdest doch mit deiner Herangehesnweise den Fehler auch nicht bemerken, da der Unterschied ja nur ist wo wir beide die Fehler abfangen - nicht das wir sie abfangen.

Aus diesem Grund wurde das Unittesting "erfunden": Komponenten werden möglichst unabhängig getestet

Es wurde vieles erfunden, die Frage ist jedoch immer ob der Kunde es will. Wenn ich in einem Projekt NUnit einsetzen kann tue ich es - aber ich darf mich nicht darauf verlassen das immer zu können. Im aktuellen Fall darf ich es nicht.

@Erfinder des Rates:
Visual Studio 2005, fx Extension, Framework 3.0, MSDN noch auf dem Stand der Erstinstallation von VS2005, kein Inet am Entwickler PC und dafür jede Menge Bücher. Und nun?

Nur mein Notebook hat iNet Zugriff und dafür muss ich mich umdrehen - ich gebe zu, ich bin faul. Und sei mal ehrich - schaust du jedesmal in die msdn wenn du einen Aufruf machst?

Ich hoffe ich darf diesen Thread benutzen. Der Titel ist mir in der SuFu aufgefallen, der Thread beantwortet aber meine Frage nicht.

Ist vielleicht eine Frage des Geschmacks.... Wie soll ich beim Aufruf einer Methode benachrichtigen wenn etwas schief gegangen ist?

Variante 1


public void IrgendwasMachen()
{
    Adresse adresse = new Adresse(new Guid("D3667F33-F0AB-4367-9613-AAF70F9631B3"));
    adresse.Nachname = "Meyer";
    adresse.Update();

    if (adresse.IsUpdated)
    {
        //..
    }
}

public void Update()
{
    try
    {
        // ..
        IsUpdated = true;
    }
    catch (Exception)
    {
        //...
        IsUpdated = false;
    }
}

Variante 2

public void IrgendwasMachen()
{
    Adresse adresse = new Adresse(new Guid("D3667F33-F0AB-4367-9613-AAF70F9631B3"));
    adresse.Nachname = "Meyer";
    
    if (adresse.Update())
    {
        //..
    }
}

public bool Update()
{
    try
    {
        // ..
       return true;
    }
    catch (Exception)
    {
        //...
        return false;
    }
}

Mir macht Variante 1 den "Objektorientierteren" Eindruck. Weil man ein extra dafür angelegtes Property setzt und nicht den Rückgabetyp der Methode für das Errorhandling "missbraucht". Oder ist das in Ordnung? Wie macht Ihr das?

Hallo epic_fail,

das ist ein typischer Gewissenskonflikt.

Es ist in der Tat blöd, wenn man eine Methode mit Seiteneffekt in ein if schreiben muss, zumal wenn der Seiteneffekt die eigentliche Aufgabe der Methode ist (Wobei man das natürlich durch eine Zwischenvariable vermeiden kann).

Anderseits ist es auch blöd, wenn eine Methode kein Feedback gibt und man eine extra Property dafür braucht.

Je nachdem, ob das fehlgeschlagene Update als echte Fehlersituation anzusehen ist, bliebe ja noch die Möglichkeit als Variante3, die Variante 2 ohne try/catch und ohne return zu verwenden.

herbivore

Ich häng mich auch mal hier ran weils grad dazupasst...
Ich mag so viele try/catches auch nicht und benutze sie nur wenn es nötig ist. Ansonsten prüf ich lieber ab.
Die Frage passend zum Threadtitel mit dem Programmierstil, wie handhabt ihr das bei komplexen Abfragen?
Ich hab drei Varianten, ich möchte in jedem Fall wissen, woran der Fehler lag...


// VARIANTE 1, mit try-catch, und ich nehm ne Variable die speichert wo ich grad bin
int error = 0;
try
{
  error = 1
  Funktion(x); // x könnte null sein

  error = 2;
  Funktion(x.y); // y könnte null sein

  error = 3;
  Funktion(x.y.z); // z könnte null sein

  // Routine beendet, jetzt ist Fehler wieder 0.
  error = 0;
}
catch(NullPointerException ex)
{
   Console.Writeline(string.concat("Fehler ", error, \n, ex.Message));
}
return error;


// VARIANTE 2, ohne try/catch, mit mehreren Funktionsausgängen

if (x == null)
  return 1;
  
Funktion(x);

if (x.y == null)
  return 2;

Funktion(x.y);

if (x.y == null)
  return 3;

Funktion(x.y.z);

return 0;



// Variante 3 verschachtelte ifs
int error = 0;
if (x != null)
{
  Funktion(x);
   if (x.y != null)
  {
    Funktion(x.y);
    if (x.y.z != null)
    {
       Funktion(x.y.z);
    }
    else
    {
       error = 3;
    }
  }
  else
  {
     error = 2;
  } 
}
else
{
  error = 1;
}
return error;

Welche Variante ist die "schönste" oder ist das alles Geschmacksfrage?
Bei der letzteren machen mich die vielen Klammern ganz verrückt, bei zweiterer hab ich mehrere Returns, es gibt ja Programmierrichtlinien die das verteufeln (trotzdem ist das die Variante die ich am öftesten verwende da es am übersichtlichsten ist, erfreulicherweise hat man bei uns die 1-Return-Regel aus den Programmierrichtlinien wieder rausgenommen), und Variante 1 sieht irgendwie steinzeitlich aus.
Also, wie macht ihr das (ich prüfe jetzt in dem Beispiel auf null aber es könnt auch was anderes sein das voneinander abhängig ist)?

gruß
sth_Weird

++++++++++++++++++++~+
Fluchen ist die einzige Sprache, die jeder Programmierer perfekt beherrscht


Linux is for free...if your time is worth nothing
++++++++++++++++++++~+

Hallo sth_Weird,

Variante 3 finde ich - wie du - grauslich.

Gegen mehrere returns spricht aus meiner Sicht (spätestens seit es finally gibt) überhaupt nichts (mehr).

Wirklich gut finde ich keine der Varianten. Da man aber als Aufrufer Parameter selbst auf null prüfen sollte, wenn null nicht erlaubt ist, statt eine ArgumentNullExcption zu provozieren, spricht das in der konkreten Situation für Variante 2.

herbivore

Hi,
ich habe mir jetzt nicht alle Post durchgelesen, wollte aber mal einwerfen, dass in Java ein deutlich "strengeres" Exception-Handling durchgesetzt wird. So muss jede Methode entweder die Exceptions, die auftreten können abfangen oder anzeigen, welche sie werfen könnte. Der Vorteil, der sich aus meiner Sicht daraus ergibt ist, dass nie ein Fehler wirklich die "Oberfläche" erreicht, also unbehandelt durchgereicht wird, was je bei .NET meistens das Programm zum Absturz bringt.

http://java.sun.com/docs/books/tutorial/essential/exceptions/

Hallo Kevka,

ja, das ist bekannt. Inbesondere svensons hat sich (in anderen Threads) schon mehrfach dazu geäußert. Hier eine kleine Auswahl:

Nein, .NET kennt keine "checked" Exceptions. Es sind ausschließlich Runtime-Exceptions. Mag man drüber streiten ob das gut so ist, war aber eine bewußte Entscheidung der .NET-Bauer.

Stichwort dazu: "Checked Exceptions".

C# und Java implementieren hier zwei Seiten eines Glaubenskrieges.

Der Grund, warum MS das nicht so wie Java gemacht hat ist sinngemäß:

"Weil kaum ein Entwickler mit dieser Flut von Exceptions umgehen kann/will (und im schlimmsten Fall deswegen alles fängt), zwingen wir den Entwicker auch nicht dazu".

Akademisch vs. pragmatisch.

Ich persönlich glaube, dass checked exceptions eine gute Lösung sind, wenn einem die viele Tipparbeit abgenommen wird (es es Eclipse offenbar tut).

Ich stelle nämlich immer wieder fest, dass "ignoriertes" Exceptionhandling eines der Hauptquellen von Fehlern ist.

Irgendwo hatte er - wenn ich mich nicht irre - auch mal einen Link zu einem Interview mit Anders Hejlsberg gepostet, wo dieser erklärt, warum es in C# keine checked exceptions gibt. Allerdings finde ich diesen gerade nicht.

herbivore

Der Vorteil, der sich aus meiner Sicht daraus ergibt ist, dass nie ein Fehler wirklich die "Oberfläche" erreicht, also unbehandelt durchgereicht wird, was je bei .NET meistens das Programm zum Absturz bringt

Das ganze nennt sich CheckedExceptions (Hatten wir da nicht schon mal eine Diskussion dazu?).

Das ganze hat aber auch Nachteile:
So kann es z.B. sehr sinnvoll, Exceptions einfach weiter durchzureichen, da es ja "Ausnahmen" sind. Manchmal will man das einfach.
Außerdem ist es meinen Erfahrungen nach nervtötend, beinahe jede Exception, die auftreten könnte irgendwie gesondert zu behandeln - vor allem, wenn man schnell Resultate braucht und eine Exception sehr unwahrscheinlich ist.
In Java Programmen werden Exceptions vermutlich deutlich schneller einfach abgefangen und nichts unternommen (vielleicht etwas Logging..)
Was ist so schlimm daran, wenn das Programm abschmiert?
Das heißt, es enthält einen Bug. Und dann sollte es auch nicht mit eventuell korrupierten Daten weiterlaufen.

Schon getippt 🙂

Hallo zusammen

Irgendwo hatte er - wenn ich mich nicht irre - auch mal einen Link zu einem Interview mit Anders Hejlsberg gepostet, wo dieser erklärt, warum es in C# keine checked exceptions gibt. Allerdings finde ich diesen gerade nicht.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

Hallo zusammen,

das Interview mit Anders Hejlsberg findet sich übrigens hier.
Interessanterweise meint er darin auch

It is funny how people think that the important thing about exceptions is handling them. That is not the important thing about exceptions. In a well-written application there's a ratio of ten to one, in my opinion, of try finally to try catch. Or in C#, using statements, which are like try finally.

Das Beispiel von sth_Weird würde ich auch eher folgendermaßen lösen:

if (x==null)
   throw new ArgrumentException("x ist null");
Funktion(x);

if (y==null)
   throw new ArgrumentException("y ist null");
Funktion(x.y);

if (z==null)
   throw new ArgrumentException("z ist null");
Funktion(x.y.z);

Die Frage wäre allerdings, ob es schlimm ist, wenn Funktion(x.y.z) nicht ausgeführt würde. (Falls nicht, finde ich Var. 2 am besten).

Gruß,
dN!3L