2011-09-12 57 views
3

这是一个相当不错的观点,我希望答案是“这不是一个热门的主意” - 这就是说,它有一点我不感兴趣,如果有人愿意放纵。我可以重写Dispose来创建一个总是调用SaveChanges的实体类吗?

型号代码:

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. 处置是正确的地方要做到这一点,因为我由于某种原因正在思考“Finalize” - 我总是对C#的破坏感到困惑。

  2. 在客户端代码中抛出异常的情况下,通常会跳过SaveChanges,这很好,但如果这种方式符合我的想法,它总是会调用它。我应该尝试用空接球吗?

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

-1处理是为了清理资源。调用SaveChanges非常糟糕。 –

+0

它是调用绑定到包含堆栈框架的范围或绑定到垃圾回收器?这就是我认为我现在真的很想知道你让我更加思考。 –

+0

你不能让任何人看到这个代码。但是,neckerhot是即使在代码抛出异常时也会调用SaveChanges()。这是一个糟糕的dbase的好方法。 –

回答

13

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

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

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

要切入此处的正确原则是:如果由于语义原因需要调用,则强制用户将代码中的呼叫置于其中。如果他们忘了这么做,他们会在测试中发现。 让用户决定是否将呼叫置于finally块中是否正确。不要为他们做出这个决定;你可能会认为错误。

+0

类似的问题和不幸的接受的答案,并没有指出,这不应该在'IDisposable.Dispose' [这里]完成(http://stackoverflow.com/questions/7295198/when-is-destructor-called-in- A-WCF服务/ 7295325#评论-8790533)。 – jason

+0

@Greg,我从一个C++程序员开始从'96到'01 ...从那时起C#我已经正确地进行了配置文件 –

0
  1. 处置在这里你可以这样做,如果你是这样做的。

  2. 这是您应该而不是做到这一点的原因之一。

+0

我想一个编程语言可能会有一个“成功块”的控制结构 –

+1

“成功块”可以结束尝试...... –

+0

这就是面向对象和体系结构的用途。创建一个具有可扩展的“成功块”的类,但可能在抽象类中使用某些基本功能来定义。 – Jaxidian

相关问题