- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑这个程序:
using System;
static class Program {
static void Main(string[] args) {
try {
try { throw new A(); }
finally { throw new B(); }
}
catch (B) { }
Console.WriteLine("All done!");
}
}
class A : Exception { }
class B : Exception { }
此处,抛出类型为 A
的异常,没有处理程序。在 finally
block 中,抛出类型为 B
的异常,该异常有一个处理程序。通常,在 finally
block 中抛出的异常会获胜,但对于未处理的异常则不同。
调试时,调试器在抛出A
时停止执行,并且不允许执行finally
block 。
当不调试时(从命令提示符独立运行),会显示(打印和崩溃对话框)关于未处理异常的消息,但在那之后,“全部完成!”确实得到打印。
当添加一个顶层异常处理程序时,除了重新抛出捕获的异常外,一切都很好:没有意外消息,并且“全部完成!”打印出来。
我明白这是怎么发生的:在执行任何 finally
block 之前确定异常是否有处理程序。这通常是可取的,并且当前的行为是有道理的。 finally
block 通常不应抛出异常。
但是this other Stack Overflow question引用 C# 语言规范并声称需要 finally
block 来覆盖 A
异常。阅读规范,我同意这正是它所需要的:
- In the current function member, each
try
statement that encloses the throw point is examined. For each statementS
, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated:
- If the
try
block ofS
encloses the throw point and if S has one or morecatch
clauses, the catch clauses are examined [...]- Otherwise, if the
try
block or acatch
block ofS
encloses the throw point and ifS
has afinally
block, control is transferred to thefinally
block. If thefinally
block throws another exception, processing of the current exception is terminated. Otherwise, when control reaches the end point of thefinally
block, processing of the current exception is continued.- If an exception handler was not located in the current function invocation, the function invocation is terminated, and one of the following occurs:
- [...]
- If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. The impact of such termination is implementation-defined.
根据我对规范的阅读,异常不会被视为未处理,直到之后所有函数调用都已终止,并且函数调用不会终止直到finally
处理程序已执行。
我是不是遗漏了什么,或者微软的 C# 实现与他们自己的规范不一致?
最佳答案
我认为问题在于 .NET 异常处理是如何构建在结构化异常处理之上的,后者对于在 finally block 中抛出的规则略有不同。
当异常 A 发生时,SEH 尝试找到第一个能够处理您的异常类型的处理程序,然后开始运行所有 finally block ,展开到它,但是基于 SEH 逻辑,没有这样的处理程序,因此它会在之前哭诉未处理的异常.NET 可以执行自己的规则。
这解释了修复问题的顶级处理程序(但只是可以处理异常类型 A 的处理程序)。
IL 本身看起来有效:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 49 (0x31)
.maxstack 1
IL_0000: nop
IL_0001: nop
.try
{
IL_0002: nop
.try
{
IL_0003: nop
IL_0004: newobj instance void A::.ctor()
IL_0009: throw
} // end .try
finally
{
IL_000a: nop
IL_000b: newobj instance void B::.ctor()
IL_0010: throw
} // end handler
} // end .try
catch B
{
IL_0011: pop
IL_0012: nop
IL_0013: ldstr "B"
IL_0018: call void [mscorlib]System.Console::WriteLine(string)
IL_001d: nop
IL_001e: nop
IL_001f: leave.s IL_0021
} // end handler
IL_0021: nop
IL_0022: nop
IL_0023: nop
IL_0024: ldstr "A"
IL_0029: call void [mscorlib]System.Console::WriteLine(string)
IL_002e: nop
IL_002f: nop
IL_0030: ret
} // end of method Program::Main
Mono有同样的问题http://ideone.com/VVoPx6
关于c# - 在 finally block 中将未处理的异常更改为已处理的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27017971/
这个问题在这里已经有了答案: How to initialize var? (11 个答案) 关闭 8 年前。 我想给一个变量赋初值 null,并在下一个 if-else block 中赋值,但是编
我正在使用 TypeScript 3.8 编写 JS 和 TS 混合的代码。我写了以下行: export * as Easing from './easing'; 应该是 fair game在 Typ
我需要将 R 代码中的“/”更改为“\”。我有这样的事情: tmp <- paste(getwd(),"tmp.xls",sep="/") 所以我的 tmp是 c:/Study/tmp.xls 我希望
我有个问题。例如我有这个: id truth count 1 1 1 2 1 2 3 0 0 4 1 1 5 1 2 6 1
我正在尝试使用“IN”和“=”来查找一些 bean。我目前正在使用此代码: $ids = array(1,2,3,4); $user = 1; $things = R::find( 'thing'
是否可以在 Xcode 中部署到其他人的手机上?我没有 iPhone,但我想测试我在 friend 手机上制作的应用程序。在我支付 99 美元之前,我想确保这不会造成麻烦。 谢谢。 最佳答案 不会有任
我试图得到一个非常大的数字(超过 unsigned long long int )。所以我把它作为一个字符串,然后一个数字一个数字地转换成整数并使用它。 #include #include int
我在 Rust 中有 C 语言库的绑定(bind),但它们并不完整。 在 C 代码中,我定义了一个简化的宏,如下所示: #define MY_MACROS1(PTR) (((my_struct1
我正在努力解决这个问题。 http://jsfiddle.net/yhcqfy44/ 动画应该自动相对于 滚动到顶部每次出现滚动条时的高度。 我已经写了这个,但没有运气: var hheight =
我正在处理一个将数字作为字符串返回的 JSON API。例如 "12" ,但是,该字段值也可以是非数字的,例如:"-" . 我已将 JSON 数据解析为映射,我想将此字段提取为 elixir 中的整数
我正在尝试编写一个类,将.wav文件转换为.aiff文件作为项目的一部分。 我遇到了几个库Alvas.Audio(http://alvas.net/alvas.audio,overview.aspx)
我想在 Lucene 中将像“New York”这样的“复合词”索引为单个术语,而不是像“new”、“york”那样。这样,如果有人搜索“new place”,则包含“new york”的文档将不会匹
我希望这个解释能让我更好地了解使用宏的优点。 最佳答案 在函数中,所有参数在调用之前都会被评估。 这意味着 or 作为函数不能是惰性的,而宏可以将 or 重写为 if 语句,该语句仅在以下情况下计算分
我有一些看起来像这样的 XML foo ]]> (注意 > 登录 "> foo")和 XSLT 样式表 当我运行xsltproc stylesheet.xs
当我尝试将 Any 转换为 List 时,如下面的示例所示,我得到“Unchecked cast: Any!”到列表'警告。有没有解决此类问题的方法? val x: List = objectOfTy
我正在使用 Python 开发一个简单的爬虫。目的是创建一个 sitemap.xml。(你可以在这里找到真正的 alpha 版本:http://code.google.com/p/sitemappy/
我想知道在 VBScript 中是否可以在多行中中断 If 语句。喜欢: If (UCase(Trim(objSheet.Cells(i, a).Value)) = "YES") Or _ (UCas
for (String item : someList) { System.out.println(item); } 使用“do while”是否等效? 谢谢。 最佳答案 如果列表为空,f
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Split string with delimiters in C 在 C 中将“,”分隔的列表拆分为数组的最佳方法
我有一个如下所示的字符数组: [0, 10, 20, 30, 670] 如何将此字符串转换为整数数组? 这是我的数组 int i=0; size_t dim = 1; char* array = (c
我是一名优秀的程序员,十分优秀!