Writing our own Dispose method instead of using Idisposable
在浏览了很多IDisposable文章之后,我对它的用法感到困惑。所有的文章都解释了它是什么以及如何实现。我想知道如果没有它我们会错过什么。它是一个包含一个方法dispose()的接口。让我们举个例子Dispose的使用通常显示为释放数据库连接。
密码应该是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Public class Test:Idisposable { public Test() { DatabaseConnection databaseConnection = new DatabaseConnection(); } public void Dispose() { if (this.databaseConnection != null) { this.databaseConnection.Dispose(); this.databaseConnection = null; } } } |
虽然已实现Dispose,但Dispose方法内部使用了DatabaseConnection的Dispose属性来释放连接(this.databaseConnection.Dispose();)
我的问题是,在这种情况下,我们为什么需要实现IDisposable?我们可以直接调用这个.databaseConnection.dispose()并释放连接。为什么在内部调用对象的Dispose属性时实现Dispose。除了IDisposable方法之外,我们还可以实现一个释放内存的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Public Class Test { public Test() { DatabaseConnection databaseConnection = new DatabaseConnection(); } public void Release() { if (this.databaseConnection != null) { this.databaseConnection.Dispose(); this.databaseConnection = null; } } } |
这两种方法有什么区别?我们真的需要我的支持吗?我期待一个具体的解释。
你是对的,使用你的发布方法,你会得到完全相同的效果,只要你总是记得调用它。
你应该使用
实现
1 2 3 4 |
使用上述代码将导致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class DotNetTips { private void DoSomeOperation() { using (SqlConnection con1 = new SqlConnection("First Connection String"), con2 = new SqlConnection(("Second Connection String")) { // Rest of the code goes here } } private void DoSomeOtherOperation() { using (SqlConnection con = new SqlConnection("Connection String")) using (SqlCommand cmd = new SqlCommand()) { // Rest of the code goes here } } } Using statement is useful when we have to call dispose method multiple times on different objects. Otherwise, we will have to call Dispose method on each object as: if (con != null) con.Dispose(); if (cmd != null) cmd.Dispose(); |
IDisposable值得实现,主要是因为它在C中是IDomatic。每个人都知道IDisposable做什么,以及如何处理实现IDisposable的对象。当您使用IDisposable.Dispose()以外的东西释放资源时,您偏离了通常理解的习惯用法。
这意味着维护人员不必知道特定类的进出口来防止资源泄漏。这甚至可能是你,在6个月内,当你忘记了你对这段代码所做的大部分工作时!您只需要知道它实现了IDisposable,这有一个通常理解的含义。
请记住,IDisposable主要是给开发人员的一个信号,"嘿,我是一个保存对非托管资源的引用的类。您可能不应该等待垃圾收集器来清理我。"请注意,这可能是通过组合间接实现的(一个实现IDisposable的类,因为它有实现IDisposable的私有成员)。当一个优秀的开发人员看到一个实现IDisposable的类时,他们应该立即认为"这个对象是特殊的,在我完成它之后需要清理它。"没有什么能阻止您编写release()方法;它只是意味着您更可能意外地泄漏资源,因为您没有使用惯用的patt恩。
你的
如果(obj是IDisposable)(idisposable)obj.dispose();
虽然不是经常做,但当它完成时,它是至关重要的。
有时,如果可能有人想在对象使用期间调用它,那么拥有一个类似于
在将来的某个不确定的点上,托管对象将由垃圾收集自动处理。但是,在处理可能包含非托管资源(不受clr/垃圾收集控制)的对象时,应实现IDisposable,以提供将这些资源返回到操作系统的一致且确定的方法。
当对象在using()的上下文中使用时,接口只提供任何真正的好处。块。这样的块告诉clr,当Dispose方法碰到块的右大括号时,调用它。因此,无论此块中发生什么(除了一些灾难性的系统故障),都保证调用Dispose方法并释放非托管资源。
例如,在您提供的代码中,如果引发了异常,则可能永远不会调用您的release()方法,这可能会使连接保持打开状态。但是,当使用带有using块的可释放对象时,当抛出异常时,clr将在抛出异常之前跳入并调用Dispose方法。