如果使用IDisposable
类,我是否应该始终使用using
子句,例如:
using (MyClass myclass = new MyClass())
{
...
}
答案 0 :(得分:4)
using
语句确保调用Dispose
以释放资源,即使发生异常或对象超出范围也是如此。
这比使用以下代码块
更简单try
{
...
}
catch()
{
// Handle exception
}
finally
{
// Free resources by calling Dispose()
}
注意
如果不想处理catch
,则不需要exception
块。在这种情况下,try
... finally
块就足够了(正如其他答案所指出的那样)。
替代方式
您可以在同一个using语句中创建多个一次性对象的实例,例如
using(MyClass myclass1 = new MyClass(),
MyClass myclass2 = new MyClass())
{
...
}
实施例
来自Understanding the 'using' statement in C#
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
被翻译为(CLR)
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes!= null)
{
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}
}
您可以查看示例开头指定的链接中生成的MSIL。
更多信息
答案 1 :(得分:2)
它使代码更具可读性。因此,作为规则,您应该在using块中声明和实例化对象。它确保即使发生异常也会调用Dispose方法。在编译时,相同的表达式看起来像this:
{
MyClass myclass = new MyClass ();
try {
//Do something with myclass
}
finally {
if (myclass != null)
((IDisposable)myclass).Dispose();
}
}
答案 2 :(得分:0)
using子句是以下代码块中的语法糖:
MyClass myclass = null;
try
{
myclass = new MyClass();
//do work
}
finally
{
if(myclass != null)
myclass.Dispose();
}
如果一个类实现了IDisposable,那么在使用它时应该确保调用Dispose。 using子句只是一种简单的方法。所以你不必使用“使用”来做,但你应该确保它被调用。
答案 3 :(得分:0)
如果某个类实现了IDisposable
,那么在完成该对象后,应始终调用Dispose
。 C#提供using语句作为语法糖,使这更容易。因此,不需要使用using
来呼叫Dispose
。也就是说,这是调用Dispose
的事实上的标准方式。即如果你的代码没有使用using
而是在finally块中调用Dispose
,那么对于有经验的编码人员来说,这看起来有点奇怪。
使用块的扩展(假设MyClass是引用类型)是:
{
MyClass myclass = new MyClass();
try {
//...
}
finally {
if (myclass != null) ((IDisposable)myclass).Dispose();
}
}
using
版本更易于编码且更易于阅读。
答案 4 :(得分:0)
简单地说,如果它实现了IDisposable,并且你想要调用该方法(当你在做的时候也在finally块中的例外。使用。
GC不会为您调用Dispose()!有些类实现了终结器~ClassName()但是尽量避免这种情况,因为它有很多副作用并且不明显。
您可以将using语句读作:
TestClass test = new TestClass();
try
{
test.DoSomething();
}
finally
{
test.Dispose();
}
答案 5 :(得分:0)
只要对象的生命周期足够短以至于可以实现,就应该始终这样做。有时您必须单独处理清理,因为您拥有长寿命的对象,这些对象在代码块完成后会持续很长时间。
答案 6 :(得分:0)
创建IDisposable对象时有三种情况:
在场景#1中,使用“using”块来创建对象;它的清理工作将自动处理。
在场景#2中,使用带有“ok”变量的“try-finally”块,该变量最初设置为“False”,但在“try”结束时或在任何返回之前设置为“True”;在finally中,如果“oK”为false,则调用Dispose以确保部分构造的对象被清除。
在场景#3中,一旦创建了对象,就将其存储在字段中,并定义一个IDisposable.Dispose方法,该方法将字段中的值复制到变量中,将该字段归零,如果变量为非变量-null,Dispose it(如果有多个线程同时调用Dispose的可能性,请使用Interlocked.Exchange来锁定并清除该字段)。构造函数也应该像场景#2中的函数一样受到保护。