osc*_*tin 49 .net c# vb.net idisposable using
我的理解是,一旦代码退出块,.NET 中的using
语句就会调用IDisposable
对象的Dispose()
方法.
using
声明是否还做其他事情?如果没有,似乎以下两个代码示例实现完全相同的事情:
Using Con as New Connection()
Con.Open()
'do whatever '
End Using
Dim Con as New Connection()
Con.Open()
'do whatever '
Con.Dispose()
Run Code Online (Sandbox Code Playgroud)
我会给那些确认我是正确的人或者指出我错了并给出解释原因的人给出最好的答案.请记住,我知道某些类可以在其Dispose()
方法中执行不同的操作.这个问题是关于using
语句是否达到与调用对象Dispose()
方法完全相同的结果.
Bri*_*haw 66
using
基本上相当于:
try
{
// code
}
finally
{
obj.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
因此,Dispose()
即使在块内的代码中抛出未处理的异常,它也具有调用的好处.
Sar*_*yan 20
正如Brian Warshaw在这里所说,它只是一个实现try
和finally
阻止以确保对象被处置.除了他的答案之外,using
阻止还确保即使您使用范围返回内部也会处置该对象.
我曾经对此感到好奇并使用以下方法对其进行了测试:
自定义IDisposable测试类和Main
private class DisposableTest : IDisposable
{
public string Name { get; set; }
public void Dispose() { Console.WriteLine("{0}.Dispose() is called !", Name); }
}
public static void Main(string[] args)
{
try
{
UsingReturnTest();
UsingExceptionTest();
}
catch { }
try
{
DisposeReturnTest();
DisposeExceptionTest();
}
catch { }
DisposeExtraTest();
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
测试用例实现
private static string UsingReturnTest()
{
using (DisposableTest usingReturn = new DisposableTest() { Name = "UsingReturn" })
{
return usingReturn.Name;
}
}
private static void UsingExceptionTest()
{
using (DisposableTest usingException = new DisposableTest() { Name = "UsingException" })
{
int x = int.Parse("NaN");
}
}
private static string DisposeReturnTest()
{
DisposableTest disposeReturn = new DisposableTest() { Name = "DisposeReturn" };
return disposeReturn.Name;
disposeReturn.Dispose(); // # IDE Warning; Unreachable code detected
}
private static void DisposeExceptionTest()
{
DisposableTest disposeException = new DisposableTest() { Name = "DisposeException" };
int x = int.Parse("NaN");
disposeException.Dispose();
}
private static void DisposeExtraTest()
{
DisposableTest disposeExtra = null;
try
{
disposeExtra = new DisposableTest() { Name = "DisposeExtra" };
return;
}
catch { }
finally
{
if (disposeExtra != null) { disposeExtra.Dispose(); }
}
}
Run Code Online (Sandbox Code Playgroud)
而输出是:
//preceeding code
using (con = new Connection()) {
con.Open()
//do whatever
}
//following code
Run Code Online (Sandbox Code Playgroud)
相当于以下(注意con的范围有限):
//preceeding code
{
var con = new Connection();
try {
con.Open()
//do whatever
} finally {
if (con != null) con.Dispose();
}
}
//following code
Run Code Online (Sandbox Code Playgroud)
这里描述:http://msdn.microsoft.com/en-us/library/yh598w02.aspx
using语句确保即使在对象上调用方法时发生异常,也会调用Dispose.您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果; 实际上,这就是编译器如何翻译using语句.
一个using
说法是清晰的,比一个更简洁的try...finally{Dispose()}
构造,并应在几乎所有情况下,人们不希望允许退出块没有被使用Dispose
被调用."手动"处置更好的唯一常见情况是:
请注意,IDisposable
从工厂方法返回时,应使用以下内容:
bool ok = false; DisposableClass myThing; try { myThing = new DisposableClass(); ... ok = true; return myThing; } finally { if (!ok) { if (myThing != null) myThing.Dispose(); } }
确保如果没有返回myThing
将获得Dispose
d.我希望有一种方法可以使用using
一些"取消Dispose"方法,但不存在这样的事情.
两者之间的区别在于,如果抛出了异常
Con.Open()
'do whatever
Run Code Online (Sandbox Code Playgroud)
Con.Dispose
不会被叫.
我不是用VB语法,但在C#中,等效的代码就是
try
{
con = new Connection();
// Do whatever
}
finally
{
if (con != null) con.Dispose();
}
Run Code Online (Sandbox Code Playgroud)