这两段代码之间是否有任何区别?哪种方法更好。
try
{
using()
{
//Do stuff
}
}
catch
{
//Handle exception
}
using()
{
try
{
//Do stuff
}
catch
{
//Handle exception
}
}
答案 0 :(得分:30)
存在差异,但它归结为使用块创建自己的try和scope块。
try
{
using(IDisposable A = GetDisposable())
{
//Do stuff
}
}
catch
{
//Handle exception
// You do NOT have access to A
}
using(IDisposable A = GetDisposable()) //exception here is uncaught
{
try
{
//Do stuff
}
catch
{
//Handle exception
// You DO have access to A
}
}
答案 1 :(得分:8)
这些块之间存在差异。在第二种情况下,如果在using()行中抛出异常,则不会捕获异常(例如,实例化IDisposable对象并且构造函数抛出异常)。哪一个更好将取决于您的具体需求。
答案 2 :(得分:5)
是。在第一个中,您正在“使用”的资源将在执行catch块之前被释放。在后来,它将在之后处理。而且,“foo”语句不在catch子句的范围内。 “使用”块是几乎语法糖,这样
using (foo)
{
}
是
try
{
foo;
}
finally
{
foo.Dispose();
}
没有上下文,哪种行为“更好”并不明显。
答案 3 :(得分:3)
最终,您可以结合使用这两种方法来克服缺点:
IFoo f;
try{
f = new Foo();
f.Bar();
catch{
// Do something exceptional with f
} finally{
if(f != null) f.Dispose();
}
答案 4 :(得分:2)
我认为你的意思是:
using (var x = new Y(params))
{
}
在这两种情况下?然后明显的区别是 x 的范围。在第二种情况下,您可以在catch子句中访问 x 。在第一种情况下,你不能。
我也会借此机会提醒你不要“处理”一个例外情况,除非你能真正做些什么。这包括记录异常,这是可以的,除非您正在操作的环境为您执行日志记录(默认情况下是ASP.NET 2.0)。
答案 5 :(得分:2)
如上所述,只有第一种方法会捕获IDisposable对象初始化中的异常,并且将使对象具有catch块的范围。
此外,catch和finally块的操作顺序将根据其嵌套进行翻转。请看以下示例:
public class MyDisposable : IDisposable
{
public void Dispose()
{
Console.WriteLine("In Dispose");
}
public static void MethodOne()
{
Console.WriteLine("Method One");
using (MyDisposable disposable = new MyDisposable())
{
try
{
throw new Exception();
}
catch (Exception ex)
{
Console.WriteLine("In catch");
}
}
}
public static void MethodTwo()
{
Console.WriteLine("Method Two");
try
{
using (MyDisposable disposable = new MyDisposable())
{
throw new Exception();
}
}
catch (Exception ex)
{
Console.WriteLine("In catch");
}
}
public static void Main()
{
MethodOne();
MethodTwo();
}
}
这将打印:
Method One
In catch
In Dispose
Method Two
In Dispose
In catch
答案 6 :(得分:1)
using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器如何翻译using语句。
using (Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}
与
相同{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}