2009-06-02 8 views
6

Wie formatierst du deine try..catch.finally Blöcke? Vor allem, wenn ich nur eine kleine Menge Code einpacke, bläst es alles und macht Code meiner Meinung nach unleserlich und unansehnlich.Formatierung von schwer zu lesen versuchen..catch..finally Blöcke?

wie:

try 
{ 
    MyService service = new Service(); 
    service.DoSomething(); 
    return something; 
} 
catch (Exception ex) 
{ 
    LogSomething(); 
    return somethingElse; 
} 
finally 
{ 
    MarkAsComplete(); 
    service.Dispose(); 
} 

Diese 7 Zeilen Code verwandelte sich in einen 16-Zeilen-Durcheinander.

Irgendwelche Vorschläge für einen besseren Versuch..Catch..finally Formatierung?

+4

Sie haben bereits die ideale Format. –

Antwort

6

Eigentlich liest sich das sehr gut zu mir. Wenn Ihr Code wirklich so aussieht, würde ich mir darüber keine Sorgen machen. Es ist SEHR klar, was passiert.

Wenn Ihr tatsächlicher Code komplexer ist, dann überlegen Sie, die Blöcke in wohl benannte Methoden zu zerlegen.

+1

Unabhängig davon, welche Position Sie bei der Platzierung von Klammern oder Leerzeichen oder Einrückungsbeträgen haben, sollten Sie komplexe Code-Blöcke immer in gut benannte Methoden aufteilen. http: // coliveira.net/2009/05/tag-2-write-short-methods/ –

1

Leerzeichen. Als Minimum lege ich immer eine Whitespace-Zeile vor jede return-Anweisung und dazwischen zwischen "doing stuff" und "creating variables".

try 
{ 
    MyService service = new Service(); 

    service.DoSomething(); 

    return something; 

} 
catch (Exception ex) 
{ 
    LogSomething(); 

    return somethingElse; 

} 
finally 
{ 
    MarkAsComplete(); 
    service.Dispose(); 
} 

viel besser.

+0

Obwohl ich mich nicht zu 100% daran halte, tendiere ich auch dazu, dieses Format einzuhalten. –

+2

Ich würde sagen, das funktioniert, wenn Sie eine ganze Reihe von Zeilen haben, aber in diesem Fall sieht es zu spärlich aus. – Neil

+0

Für diesen Fall kann es sein. Ich persönlich versuche, in meinem Coding-Stil konsistent zu bleiben und dies unabhängig davon, ob es 3 Zeilen oder 10 Zeilen in einem Versuch/Catch-Block gibt. –

4

Nun, ich denke, das ist gut so. Einige davon werden in die geschweifte Klammern Platzierung Debatte. Sie könnten dies tun:

try { 
    // 
} catch(Exception ex) { 
    // 
} finally { 
    // 
} 

Ich bevorzuge, was Sie haben. Sie sollten jedoch in Erwägung ziehen, Ihren Code so zu überarbeiten, dass er nur eine Return-Anweisung enthält. Ich finde, das ist ein wenig besseres Design.

+1

Willkommen bei The One True Brace Style! – Richard

2

formatiere ich den Code mit den Klammern auf der gleichen Linie:

try { 
    MyService service = new Service(); 
    service.DoSomething(); 
    return something; 
} catch (Exception ex) { 
    LogSomething(); 
    return somethingElse; 
} finally { 
    MarkAsComplete(); 
    service.Dispose(); 
} 

Ich ziehe es leere Zeilen hinzufügen, wenn ich mehr Abstand möchten. Das funktioniert auch als Trennzeichen zwischen logischen Code-Blöcken.

+0

Ich denke, das macht es noch schlimmer :-) – hdoghmen

0

Ich denke, Ihre Formatierung liest auch gut. Mein Vorschlag wäre, die catch-Anweisung nur sparsam zu verwenden. Benutze es nur, wenn du etwas fangen musst. Andernfalls können Sie zulassen, dass andere Teile des Programms die Ausnahme behandeln. Das ganze "fail early" -Konzept.

try 
{ 
    //do something that may throw an exception. 
} 
finally 
{ 
    //handle clean up. 
} 

//let a method further down the stack handle the exception. 
0

Persönlich neige ich dazu, den vorhergehenden Stil in meinem Code zu folgen ... Es gibt Zimmer Kommentare zu machen, und zeigt den Ablauf meiner Logik besser.

Ich habe ein Widescreen, dass ich es auf der Seite, so dass die Whitespace lässt die verschiedenen Spalten gut ausrichten und tut mir nicht so weh, weil ich so viel Bildschirm Immobilien wie es ist ...

try { // getting a service 

    MyService service = new Service(); 
    service.DoSomething(); 

    return something; 

} 

catch (Exception ex) { // the fact that a service might be full/timedout 

    LogSomething(); 

    return somethingElse; 

} 

finally { // remove any resources the service may still hold. 

    MarkAsComplete(); 
    service.Dispose(); 

} 
1

Sie könnten über Container denken (sehr intelligente Fabriken) und Beratung (behandeln alle unordentlich Details).

Dear Mr. Container Sir, 
Whenever I request from you an instance object of the interface ISomething, 
    please construct for me an instance of the concrete class SomethingImpl; 
    in addition, please see to it (however you do it) that, whenever I call a 
    method on this instance, it is wrapped within a complicated and messy try- 
    catch-finally which logs exceptions and mark calls as completed. That way, 
    all I have to do is write the business logic that goes into the SomethingImpl 
    and I don't have to worry about all the messy infrastuctural details. 
Sincerely, 
Mr. Agile. 

Man könnte dies sehen, im Code, wie:

//a class that knows how to take care of the messy infrastructure details 
public class MyMessyInterceptor : IInterceptor { 
    public void Intercept(IInvocation invocation) { 
     //handle the messy details of continuing with the method-invocation, 
     //but within a try-catch-finally that includes exception handling and 
     //call logging. 
    } 
} 

//a function that will configure a container (very smart factory) 
public IContainer CreateContainer() { 
    var builder = new ContainerBuilder(); 

    //tell the container-builder about the interceptor 
    builder 
     .Register(c => new MyMessyInterceptor()) 
     .Named("keep-my-code-clean") 
    ; 

    //tell the container what to do when you ask it for a ISomething 
    builder 
     .Register<SomethingImpl>() 
     .As<ISomething>() 
     .InterceptedBy("keep-my-code-clean") 
    ; 

    return builder.BuildContainer(); 
} 

//some function out there in your code somewhere that needs to make a 
//service call; there's hundreds of functions out there just like this 
//in your code, and they all just got much simpler 
public object GottaGoDoSomething() { 
    //find the container 
    var container = GetTheSingletonContainerObject(); 
    //ask for an instance of ISomething - it knows to provide a 
    //SomethingImpl wrapped in an interceptor that takes care of all 
    //the logging and exception handling 
    var something = container.resolve<ISomething>(); 
    //call the big method 
    return something.DoSomething(); 
    //magically (not really), the exception handling and logging are 
    //already taken care of 
} 

mit der Interceptor-Klasse nur einmal Coming up passiert. Die Registrierung jeder Interceptor- und Serviceklasse erfolgt ebenfalls nur einmal.Das Einrichten des Containers (sehr Smart Factory) ist sicherlich kompliziert.

Allerdings muss jeder Ort in Ihrem Code, der das Serviceobjekt verwenden muss und diesen in komplizierte und unordentliche Infrastrukturdetails wie Ausnahmebehandlung und Protokollierung einbetten muss, einfach sehr sauber und sehr unkompliziert werden. Es gibt nur eine CreateContainer, aber es gibt Hunderte von GottaGoDoSomething s, so dass eine ganze Menge von einfachen auf Kosten von ein wenig kompliziert ist.

(Hinweise: Das Codebeispiel verwendet das Autofac-Containerframework und das Castle-Interceptorframework. Ich weiß, dass dies ein Beispiel für das Dienstortmuster ist, nicht das Abhängigkeitsinjektionsmuster, aber der Punkt war, Interzeptoren zu veranschaulichen und sie mit einem Container registrieren, um die Abhängigkeitsinjektion nicht darzustellen.

0

Ich auch, wie, was Sie ursprünglich hatten. Physische Zeilen in einer CS-Datei kosten nichts und ändern den endgültigen Ausgabecode nicht. Verwenden Sie also alles, was Sie brauchen, um für Sie oder Ihr Team die beste Lesbarkeit zu gewährleisten.

In der Tat sollten Sie tatsächlich versuchen, mehr Zeilen als die 16 verwenden, die Sie hier zeigen, wenn Sie Code, indem Sie Kommentare für sich selbst oder andere hinzufügen.

von

// a comment that says what's going on 

häufig hinzufügen, können Sie sich besser daran erinnern, was dieser Try.Catch tun werden soll, wenn Sie es nach 6 Monaten zurück.

4

Sie können einen using Block anstelle einer expliziten Dispose() verwenden, sonst müssen Sie Wahrscheinlichkeit für Null überprüfen, bevor Sie es entsorgen, using Blöcke macht das für Sie. Leider erhöht es die Verschachtelung =/

+0

Es gibt kein "leider" darüber. Der 'using'-Block ist definitiv die bevorzugte Methode, um eine Ressource nach der Verwendung * von * für einen Codeabschnitt zu disponieren. –

0

Ich versuche immer und Refactor alle meine Versuch Catch Blöcke und kapseln sie in ihrer eigenen Methode.

Dies scheint immer alles lesbarer zu machen, und es ist eine gute Programmierpraxis, dass Ihre Methoden nur eine Sache machen. Wenn Sie über und unter Ihrer try-catch-finally-Anweisung Code haben, haben Sie wahrscheinlich mehr als eine Sache.

0

Wenn Sie wirklich wollen, um loszuwerden, der obligatorisch aber hässlich Formatierung (ja, ich zustimmen: p)

für Aspect gehen Programing Oriented, und Sie werden den Versuch erhalten ... catch ... endlich eingebettet kostenlos in Ihrer Assembly und Ausnahme automatisch protokolliert.

Versuchen PostSharp oder Spring.Net

Verwandte Themen