C#:IDisposable 类需要“使用”条款?
如果我使用 IDisposable
类,我是否应该始终使用 using
子句,例如:
using (MyClass myclass = new MyClass())
{
...
}
If am using an IDisposable
class, should I always use a using
clause, for example:
using (MyClass myclass = new MyClass())
{
...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
using
语句确保即使发生异常或对象超出范围,也会调用Dispose
来释放资源。这比使用以下代码块更简单,
注意
如果不想处理
异常
,则不需要catch
块。在这种情况下,一个try
...finally
块就足够了(正如其他答案中指出的那样)。替代方式
您可以在同一个 using 语句中创建一次性对象的多个实例,例如
示例
从 理解 C# 中的 'using' 语句
被翻译为(由 CLR)
您可以查看在示例开头指定的链接中生成了 MSIL。
更多信息
The
using
statement ensures thatDispose
is called to free the resources even if an exception occurs or if the object goes out of scope.This is simpler than using the following code block,
Note
The
catch
block is not necessary if one does not want to handle theexception
. In that case, atry
...finally
block would suffice (as pointed in other answers).Alternative way
You can create multiple, instance of the disposable object in the same using statement, for example
Example
From Understanding the 'using' statement in C#
gets translated to (by the CLR)
You can have a look at the generated MSIL in the link specified at the beginning of the example.
More information
它使其代码更具可读性。因此,通常您应该在 using 块中声明并实例化该对象。它确保即使发生异常也会调用 Dispose 方法。在编译时,相同的表达式将类似于这样:
It makes it much more readable code. So, as a rule you should declare and instantiate the object in a using block. It ensures that the Dispose method is called even if an exception happens. At compile time the same expression would look something like this:
如果一个类实现了
IDisposable
,那么当您处理完该对象后,您应该始终调用Dispose
。 C# 提供了 using 语句作为语法糖,以简化此操作。因此,不需要使用using
来调用Dispose
。也就是说,它是调用 Dispose 的事实上的标准方法。即,如果您的代码没有使用using
而是在finally 块中调用Dispose
,那么对于经验丰富的编码人员来说,它看起来会有点奇怪。using 块的扩展(假设 MyClass 是引用类型)是:
using
版本更易于编码且更易于阅读。If a class implements
IDisposable
you should always callDispose
when you are done with the object. C# provides the using statement as syntactic sugar to make this easier. So, it's not required to useusing
to callDispose
. That said, it is the de facto standard way to invokeDispose
. i.e. if your code is not usingusing
and is instead invokingDispose
in finally blocks it will look a bit odd to experienced coders.The expansion of your using block (assuming MyClass is a reference type) is:
The
using
version is easier to code and easier to read.简单地说,如果它实现了 IDisposable,并且您希望调用该方法(也在您执行操作时的 finally 块中出现异常时)。请使用 using。GC
不会为您调用 Dispose()!有些类实现了终结器 ~ClassName () 但尽量避免这种情况,因为它有很多副作用并且不明显,
您可以将 using 语句读为:
Simply put, if it implements IDisposable, and you want to have that method called (also on exceptions in the finally block when you are doing. Use using.
The GC will NOT call Dispose() for you! Some classes implement a finalizer ~ClassName() but try to avoid this because it has many side effects and is not obvious.
You can read an using statement as:
只要对象的生命周期足够短,您就应该始终这样做。有时,您必须单独处理清理工作,因为您的对象具有较长的生命周期,这些对象在代码块完成后仍将持续很长时间。
You should always do it so long as the lifetime of the object is short enough that this is possible. Sometimes you have to handle the cleanup separately because you have objects with a long lifetime that will persist long after the block of code is done.
创建 IDisposable 对象时存在三种情况:
在场景#1中,使用“using”块来创建对象;其清理工作将自动进行。
在场景 #2 中,使用带有“ok”变量的“try-finally”块,该变量最初设置为“False”,但在“try”结束时或在任何返回之前设置为“True”;最后,如果“oK”为 false,则调用 Dispose 以确保部分构造的对象得到清理。
在场景 #3 中,对象创建后立即将其存储在字段中,并定义一个 IDisposable.Dispose 方法,该方法会将字段中的值复制到变量中,将字段清空,如果变量非空,处理它(如果有可能多个线程同时调用 Dispose,请使用 Interlocked.Exchange 来锁定并清除该字段)。构造函数也应该像场景 #2 中的函数一样受到保护。
There are three scenarios when an IDisposable object is created:
In scenario #1, use a "using" block to create the object; its cleanup will be handled automatically.
In scenario #2, use a "try-finally" block with an "ok" variable that's set to "False" initially but is set to "True" at the end of the "try" or just before any return; in the finally, if "oK" is false, call Dispose to ensure the partially-constructed object gets cleaned up.
In scenario #3, store the object in a field as soon as it's created, and define an IDisposable.Dispose method which will copy the value in the field to a variable, null out the field, and if the variable was non-null, Dispose it (if there's any possibility of multiple threads calling Dispose simultaneously, use Interlocked.Exchange to latch and clear the field). Constructors should also be protected as would functions in scenario #2.
using 子句是以下代码块的语法糖:
如果类实现了 IDisposable,则应确保在使用完它后调用 Dispose。 using 子句只是一种简单的方法。所以你不必使用“using”来做到这一点,但你应该确保它被调用。
the using clause is syntax sugar on the following code block:
If a class implements IDisposable you should ensure that Dispose is called when you are done using it. The using clause is just an easy way to do it. So you don't have have to use "using" to do it, but you should ensure that it is called.