7

私が迷っているコーディングスタイルの問題について、あなたの意見を知りたいです。おそらく決定的な答えはないことは承知していますが、いずれかの方向に強い好みがあるかどうかを確認したいと思います.

usingかなりの数の場所にステートメントを追加するソリューションを検討しています。多くの場合、次のようなものに出くわします。

{
    log = new log();
    log.SomeProperty = something;  // several of these
    log.Connection = new OracleConnection("...");
    log.InsertData(); // this is where log.Connection will be used
    ... // do other stuff with log, but connection won't be used again
}

log.Connection は、IDisposable を実装する OracleConnection です。

私のニートニックはそれを次のように変更したいと考えています:

{
    using (OracleConnection connection = new OracleConnection("..."))
    {
        log = new log();
        log.SomeProperty = something;
        log.Connection = conn;
        log.InsertData();
        ...
    }
}

しかし、簡潔さを好み、仕事を少し速く終わらせたい人は、次のことをしたいと考えています。

{
    log = new log();
    log.SomeProperty = something; 
    using (log.Connection = new OracleConnection("..."))
        log.InsertData();
    ...
}

どういうわけか、これを行うと少し汚いと感じます。これは悪いことだと思いますか?これが悪いと思うなら、それはなぜですか?良かったら、どうして?

編集: これは、多くの例の 1 つの (やや不自然な) 例であることに注意してください。これは、よく考えられていないインターフェイスを持つロガー クラスを示しているという事実に固執しないでください。これは私の質問とは関係ありません。とにかく、クラス自体を改善する自由はありません。

4

5 に答える 5

5

彼らは両方とも恐ろしいです。どちらもしないでください。

あなたはここで私が「ハイメンテナンスクラス」と呼んでいるものを作っています。高度な保守クラスには、「大量のリソースを提供する必要があります。リソースの使用が終了したら、それらを適切にクリーンアップする必要があります」という契約があります。この契約は、クラスのユーザーがクラスがどのように実装されているかを知る必要があることを意味します。これにより、最初にクラスを作成する動機となったカプセル化と抽象化の原則に違反します。

あなたのコメントでこれを伝えることができます:これは接続が使用される場所です, 私は接続が再び使用されないことを知っています. どうしてわかるの?それがクラスの文書化された契約である場合にのみ、それを知っています。これは、クラスの消費者に課すのに適した契約ではありません。

これを改善するいくつかの方法:

1) ロガーを使い捨てにする。完了したら、接続をクリーンアップします。これの欠点は、ロガーが必要以上に長く接続を保持することです。

2) InsertData が接続をパラメーターとして受け取るようにします。ロガーは接続を保持しないため、呼び出し元は引き続き接続をクリーンアップする責任があります。

3) 3 番目のクラス「Inserter」を作成します。これは使い捨てで、コンストラクターでログと接続を受け取ります。インサーターは、接続が破棄されるときに接続を破棄します。呼び出し元は、インサーターを破棄する責任があります。

于 2010-05-20T23:25:35.237 に答える
2

私はあなたのニートニクに耳を傾けます。個人的には彼のやり方の方が好きです。

于 2010-05-20T23:25:26.543 に答える
2

log理想的にはそれ自体を実装する必要があることに同意しますIDisposableが、それが不可能であると仮定して、OPが実際に尋ねた質問に対処しましょう。

2 番目の方法の方が優れています。単純に、同じことを行うコードが少ないからです。connectionここで追加の変数を導入しても利点はありません。

usingまた、ブロック外で他の初期化を実行できることに注意してください。ここでは問題になりませんが、非常に高価なリソースを「使用」している場合は問題になる可能性があります。あれは:

log = new log();
log.SomeProperty = something; // This can be outside the "using"
using (OracleConnection connection = new OracleConnection("..."))
{
    log.Connection = conn;
    log.InsertData();
    ...
}
于 2010-05-20T23:33:52.403 に答える
1

2 つの使用方法usingは完全に同等です。どちらの方法でも、ログはスコープ内にあるものの、接続が破棄されたままになります。ログを使い捨てにして、dispose メソッドでその接続を破棄し、ログを接続自体ではなく using ステートメントに配置する方がはるかに優れています。

于 2010-05-20T23:28:24.600 に答える
0

logが IDisposable を実装している場合は、中かっこが明示的であるため、2 番目の選択肢を実行します。場合によっては、複数のusingステートメントを使用できます。

using (Graphics g = ...)
using (Pen p = new Pen ...)
using (Font f = new Font ...)
{



}

1セットのブレースのみを使用して逃げることができる場所。これにより、クレイジーなインデントが回避されます。

于 2010-05-20T23:27:53.250 に答える