2009-06-02 13 views
6

try..catch.finallyブロックをどのようにフォーマットしていますか?特に少量のコードだけをラップすると、それはすべてを吹き飛ばし、私の意見ではコードを読みにくく見苦しくします。このようにtry..catch..finallyブロックを読みにくいフォーマットにするには?

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

コードのこれらの7株は16ラインの混乱になりました。

より良いtry..catch..finallyフォーマットについての提案はありますか?

+4

Spring.Netあなたは既に理想的な形式を持ってしてみてください。 –

答えて

6

実際、これは私にとって非常によく読んでいます。あなたの実際のコードがこのように多く見える場合、私は本当にそれについて心配しません。何が起きているのかがはっきりしています。

実際のコードがより複雑な場合は、ブロックを適切な名前のメソッドに分割することを検討してください。

+1

ブラケットの配置や空白、インデント量がどのようなものであれ、複雑なコードブロックを常に適切な名前のメソッドに分割する必要があります。 http:// coliveira。net/2009/05/day-2-write-short-methods/ –

1

空白。最小限の最小値として、すべてのreturnステートメントの前に、常に1行の空白を置き、コードを「実行する」と「変数を作成する」の間に置きます。

try 
{ 
    MyService service = new Service(); 

    service.DoSomething(); 

    return something; 

} 
catch (Exception ex) 
{ 
    LogSomething(); 

    return somethingElse; 

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

さらに優れています。

+0

私はそれに100%固執するわけではありませんが、私はこのフォーマットにも従う傾向があります。 –

+2

私はそれはあなたがラインの束を持っているが、この場合はあまりにも疎そうに見えるときに動作すると思います。 – Neil

+0

この場合はそうかもしれません。私は個人的に私のコーディングスタイルに一貫性を保ち、try/catchブロック内の3行か10行のどちらに関係なくこれを行うようにしています。 –

4

さて、これは問題ないと思います。この中には、中括弧配置の議論のためのものもあります。あなたはこれを行うことができます:

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

私はあなたが持っているものを好む。ただし、return文を1つだけ使用するようにコードを修正することを検討してください。私はそれが少し良いデザインであることがわかります。

+1

One True Brace Styleへようこそ! – Richard

2

私は、同じ行に括弧を使用してコードをフォーマット:私はより多くのスペースが必要な場合は空白行を追加することを好む

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

。これは、論理的なコードブロック間のセパレータとしても機能します。

+0

これは悪化させると思います:-) – hdoghmen

0

あなたの書式設定もよく読めると思います。私の提案は、catchステートメントを控えめに使用することだけです。実際に何かをキャッチする必要がある場合にのみ使用してください。それ以外の場合、プログラムの他の部分に例外を処理させることができます。全面的に「早期失敗」の概念。個人的に

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

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

、私はそれは、コメントをする余地を与え、より良い私のロジックの流れを示しています...私のコードでは、前のスタイルに従う傾向があります。

私はそれを有効にするワイドスクリーンを持っているので、空白はさまざまな列が整列するのを許し、それほどスクリーンの不動産があるので、それほど傷つけません。

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

コンテナ(非常にスマートな工場)とアドバイス(すべての面倒な詳細を処理する)について考えるかもしれません。インターセプタクラスを考え出す

//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 
} 

は一度だけ行われます

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. 

はあなたに、コード内で、これを見るかもしれません。各インターセプタとサービスクラスの登録は、一度だけ発生します。コンテナの設定(非常にスマートな工場)は確かに複雑です。

しかし、サービスオブジェクトを使用する必要があり、例外処理やロギングなどの複雑で面倒なインフラストラクチャの詳細内にそのコードを埋め込む必要がある場所はすべて、非常にきれいで、非常に単純です。 CreateContainerは1つしかありませんが、何百ものGottaGoDoSomethingがありますので、少し複雑ですが簡単です。

(注:このコード例では、AutofacコンテナフレームワークとCastleインターセプタフレームワークを使用しています。これは依存関係注入パターンではなくサービスロケーションパターンの例ですが、インターセプタ依存性注入を説明しないように容器に登録してください)。

0

私も元々のものと同じです。 .csファイルの物理行には何も費用はかかりません。最終出力コードは変更しないでください。あなたやあなたのチームに最高の可読性を提供するために必要なものすべてを使用してください。

実際には、自分自身や他の人のためにコメントを追加して、コードを書くときにここに表示される行より多くの行を実際に使用するようにしてください。

頻繁

// a comment that says what's going on 

を追加することにより、あなたはより良いあなたが6ヶ月後にそれに戻って行くときに、このTry.Catchがやっていることになっているものを思い出すことができます。

4

Dispose()の代わりにusingブロックを使用することもできます。そうしないと、廃棄する前にnullを確認する必要があります。usingブロックがそれを行います。残念ながら、ネストを増やしています。/

try 
{ 
    using(MyService service = new MyService()) 
    { 
     service.DoSomething(); 
     return something; 
    } 
} 
catch (SpecificException ex) 
{ 
    LogSomething(ex); 
    return somethingElse; 
} 
finally 
{ 
    MarkAsComplete(); 
} 
+0

それには「残念なことに」はありません。 'using'ブロックは、コードセクションに対して*使用した後にリソースを廃棄するための好ましい方法です。 –

0

私は常にtry try catchブロックをすべて試して、独自の方法でカプセル化しています。

これは常にすべてをより読みやすくするように思われます。さらに、メソッドが1つのことを行うには良いプログラミング方法です。あなたがtry-catch-finallyステートメントの上と下のコードを持っているなら、あなたは複数のことをやっているということは間違いありません。

0

あなたが本当に必須しかし醜いフォーマット(はい、私は同意する:p)を取り除くしたい場合は

プログラミング指向アスペクトのために行くと、あなたが試して取得します...キャッチ...最後に がアセンブリに埋め込まれ、例外が自動的にログに記録されます。

PostSharpまたは

関連する問題