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,这很好,但如果这按我的想法工作,它总是会调用它。我应该使用空捕获的尝试吗?

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

2 回答 2

13

不要这样做。这是个坏主意。

“Dispose”的目的是尽早礼貌地处置非托管资源,以便其他进程可以使用它。“Dispose”不应该有语义——它不应该改变你的程序的状态或以某种方式被要求。它应该只按照它所说的去做:处理资源

你应该在终结器中这样做吗? 绝对不是。那更糟。终结器可能根本不运行,终结器在另一个线程上运行,即使对象没有正确初始化,也可以调用终结器,等等。编写终结器几乎从来都不是正确的事情,如果您确实编写了终结器,它应该只处置资源。不要在终结器中做任何花哨的事情;如果你这样做,你几乎肯定会写出一个危险的不正确和脆弱的程序。

这里要遵循的正确原则是:如果出于语义原因需要调用,则强制用户将调用放入代码中。 如果他们忘记这样做,他们会在测试中发现。让用户决定将调用放在 finally 块中是否正确。不要为他们做那个决定;你可能会做出错误的决定。

于 2011-09-12T20:46:03.403 回答
0
  1. Dispose 是您要执行此操作的地方,如果您要这样做的话。

  2. 这是您不应该这样做的原因之一。

于 2011-09-12T20:40:49.643 回答