为什么使用会在';我们应该表现得像try/catch/finally
本文关键字:try finally catch 我们 为什么 | 更新日期: 2023-09-27 18:27:01
据我所知,using的工作方式类似于try/catch/finally,所以我希望如果using语句中发生异常,它会被捕获(这有点奇怪,因为这也意味着异常会被静默地吃掉)。using语句应该捕获异常并调用Dispose
方法,但这并没有发生。我设计了一个简单的测试来证明这个问题。
以下是我强制在using语句中发生异常的地方:
using (TcpClient client = new TcpClient())
{
// Why does this throw when the using statement is supposed to be a try/catch/finally?
client.Connect(null);
}
异常由client.Connect()
引发(这意味着它没有被using语句捕获,或者它被重新引发):
System.ArgumentNullException: Value cannot be null.
Parameter name: remoteEP
at System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP)
at DotNETSandbox.Program.Main(String[] args) in C:'path'to'Sandbox'Program.cs:line 42
根据微软关于该主题的一篇文章,如果Dispose
方法抛出,using语句可能会抛出。
然而,当我遵循using模式时,很明显Dispose方法不会抛出:
TcpClient c2 = new TcpClient();
try
{
c2.Connect(null);
}
catch (Exception e)
{
// We caught the null ref exception
try
{
// Try to dispose: works fine, does not throw!
((IDisposable)c2).Dispose();
}
catch (Exception e2)
{
Console.WriteLine(e2.ToString());
}
Console.WriteLine(e.ToString());
}
我有点困惑,因为我期望using
表现得像一个try/catch。有人能解释为什么会发生这种事吗?
使用is
try
{
}
finally
{
}
仅!!!
没有陷阱!
在.net中,你不必抓住例外。。
它只是一种在您离开作用域时立即调用DISPOSE方法的机制。仅此而已。
p.s.:"我怎么知道我的物体是否可以和使用一起使用?"
答案:别担心,编译时会出现错误。
using
更像是一个没有catch
的try/finally
。
控件不能在没有处理您正在使用的对象的情况下离开块,仅此而已
从块内部抛出的任何异常都将(在Disposang之后)正常传递。
编辑:根据我自己的答案,在实现IEnumerable并从using
中让步的特殊情况下,可以说你在没有调用Dispose()的情况下离开了块,但当继续枚举时,你会再次回到块内。
因为using
的行为不像try/catch/finally。它表现得像是一次尝试。
第一个例子在抛出Exception时,仍然会正确地处置TcpClient。
Using语句的行为类似于try,finally块,而不是try,catch,finally阻塞。
异常仍然会抛出using块。
它说如果Dispose()失败,它可以隐藏在using块中抛出的任何错误。
因为Dispose()发生在"finally"块内,所以如果Dispose()失败
,则在使用块外永远看不到ApplicationException