3

これはかなり細かい点であり、答えは「そもそもホットなアイデアではありません」であると予想しています。

モデルコード:

public partial class MyEntities : ObjectContext
{
    // the idea is if the object is in a using block, this always gets called?
    protected override void Dispose(bool disposing)
    {
        this.SaveChanges();
        base.Dispose(disposing);
    }
}

クライアントコード:

using(var model = new MyEntities())
{
   // do something

   // no worry about calling model.SaveChanges()
}

私が確信していない問題は次のとおりです。

  1. 何らかの理由で「ファイナライズ」を考えていたので、これを行うのに適切な場所は Dispose です - 私はいつも C# の破棄について混乱します。

  2. クライアント コードで例外がスローされた場合、通常は SaveChanges はスキップされますが、それで問題ありません。空のキャッチで try を使用する必要がありますか?

    public partial class MyEntities : ObjectContext
    {
        protected override void Dispose(bool disposing)
        {
            try
            {
               this.SaveChanges();
            }
            catch {}
            base.Dispose(disposing);
        }
    }
    
4

2 に答える 2

13

これをしないでください。それは悪い考えです。

「破棄」の目的は、管理されていないリソースを早期に丁寧に破棄して、他のプロセスが使用できるようにすることです。「Dispose」にはセマンティクスがあってはなりません。プログラムの状態を変更したり、なんらかの方法で必要になったりしてはなりません。それは、それが言うことだけを正確に行うべきです:リソースを破棄します。

ファイナライザーでそれを行う必要がありますか? 絶対にありません。それはさらに悪いことです。ファイナライザーがまったく実行されない、ファイナライザーが別のスレッドで実行される、オブジェクトが適切に初期化されていなくてもファイナライザーを呼び出すことができる、などです。ファイナライザーを作成することは、ほとんどの場合正しいことではありません。ファイナライザーを作成する場合は、リソースのみを破棄する必要があります。ファイナライザーでは、手の込んだことはしないでください。書くと、ほぼ確実に、危険なほど不正確で脆弱なプログラムを作成することになります。

ここで従うべき正しい原則は、セマンティックな理由で呼び出しが必要な場合は、ユーザーに呼び出しをコードに入れるように強制することです。 彼らがそれをするのを忘れたら、彼らはテストで見つけます。呼び出しを finally ブロックに入れることが正しいことかどうかをユーザーが判断できるようにします。彼らのためにその決定を下さないでください。あなたは間違っているかもしれません。

于 2011-09-12T20:46:03.403 に答える
0
  1. Dispose は、これを行う場合に行う場所です。

  2. これは、実行してはいけない理由の 1 つです。

于 2011-09-12T20:40:49.643 に答える