Bhu*_*tha 19 .net c# exception-handling exception
脚本
我有一个进行数据库操作的方法(比方说).如果在该操作期间引发任何异常,我只想将该异常抛给调用者.我不想在catch块中执行任何特定任务,假设调用者将对该异常执行任何操作.在这种情况下,哪一种是适当的异常处理技术?
try
{
// Some work that may generate exception
}
catch(Exception)
{
throw;
}
finally
{
// Some final work
}
Run Code Online (Sandbox Code Playgroud)
以上是等于以下try/catch/finally吗?
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
Run Code Online (Sandbox Code Playgroud)
以上是等于下面的try/finally吗?
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
Run Code Online (Sandbox Code Playgroud)
哪一个比另一个好?应该使用哪一个?
Ven*_*emo 32
不,他们不等同.在某些情况下,它们可能相同,但一般的答案是否定的.
catch块catch 具有指定异常类型的块以下内容仅捕获从中继承System.Exception然后执行finally块的托管异常,无论是否抛出异常,都会发生这种异常.
try
{
// Some work that may generate exception
}
catch (Exception)
{
throw;
}
finally
{
// Some final work
}
Run Code Online (Sandbox Code Playgroud)
catch 没有指定异常类型的块catch没有类型说明符的以下块也将捕获不一定由托管System.Exception对象表示的非托管异常,然后执行该finally块,无论是否抛出异常,都会发生该块.
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
Run Code Online (Sandbox Code Playgroud)
finally块没有catch块如果您根本没有catch阻止,finally无论是否发生异常,您仍将执行.
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
Run Code Online (Sandbox Code Playgroud)
如果您的catch块没有指定异常并且只包含该throw;语句,则后两个确实是等效的.如果您不关心非托管异常,并且您的catch块仅包含该throw;语句,则可以认为这三者都是等效的.
throw以下两段代码包含一些细微差别.后者将重新抛出异常,这意味着它将重写异常的堆栈跟踪,因此这些绝对不等同:
catch (Exception e)
{
throw;
}
Run Code Online (Sandbox Code Playgroud)
和
catch (Exception e)
{
throw e;
}
Run Code Online (Sandbox Code Playgroud)
如果您使用finallya IDisposable,以下两段代码几乎相同,但有一些细微差别:
using语句不会给你一个NullReferenceException当使用try- finally技术时,变量仍然在范围内,尽管在处理之后使用任何对象都是非常不鼓励的.但是,您仍然可以将变量重新分配给其他内容.
东西obj = null; try {obj = new Something()// do something} finally {obj.Dispose(); }
和
using (var obj = new Something())
{
// Do something
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 10
到目前为止,你有一些很好的答案,但到目前为止他们没有提到一个有趣的区别.考虑:
try { ImpersonateAdmin(); DoWork(); }
finally { RevertImpersonation(); }
Run Code Online (Sandbox Code Playgroud)
VS
try { ImpersonateAdmin(); DoWork(); }
catch { RevertImpersonation(); throw; }
finally { RevertImpersonation(); }
Run Code Online (Sandbox Code Playgroud)
假设DoWork抛出.
现在第一个问题是"是否存在可以处理此异常的catch块",因为如果答案为"否",则程序的行为是实现定义的.运行时可能会选择立即终止进程,它可能会选择在终止进程之前运行finally块,它可能会选择在未处理的异常点启动调试器,它可能会选择执行任何喜欢的操作.具有未处理异常的程序可以执行任何操作.
所以运行时开始寻找一个catch块.这个try语句中没有,所以它查找调用堆栈.假设它找到一个带有异常过滤器的.它需要知道过滤器是否允许处理异常,因此过滤器在模拟被还原之前运行.如果过滤器意外或故意做了只有管理员可以做的事情,它就会成功!这可能不是你想要的.
在第二个示例中,catch立即捕获异常,恢复模拟,抛出,现在运行时开始寻找catch块来处理重新抛出.现在,如果有一个过滤器,它将在模拟恢复后运行.(当然最终会再次恢复;我认为恢复模仿在这里是幂等的.)
这是这两个代码片段之间的重要区别.如果绝对禁止积极的任何代码,一看就知道是由尝试搞砸了,并通过清理全局状态最终,那么你最后才赶上."最后"并不意味着"立即",它意味着"最终".
| 归档时间: |
|
| 查看次数: |
2288 次 |
| 最近记录: |