5

可能重复:
最终块未运行?

我对 C# 中的 finally 块有疑问。我写了一个小示例代码:

public class MyType
{
    public void foo()
    {
        try
        {
            Console.WriteLine("Throw NullReferenceException?");
            string s = Console.ReadLine();
            if (s == "Y")
                throw new NullReferenceException();
            else
                throw new ArgumentException();          
        }
        catch (NullReferenceException)
        {
            Console.WriteLine("NullReferenceException was caught!");
        }
        finally
        {
            Console.WriteLine("finally block");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyType t = new MyType();
        t.foo();
    }
}

据我所知,不管是否抛出异常,finally 块都假设确定性地运行。现在,如果用户输入“Y” - 抛出 NullReferenceException,执行将移至 catch 时钟,然后移至 finally 块,如我所料。但是如果输入是别的东西 - ArgumentException 被抛出。没有合适的 catch 块来捕获这个异常,所以我认为执行应该移动 finally 块 - 但它没有。有人可以解释一下为什么吗?

感谢大家 :)

4

2 回答 2

6

您的调试器可能正在捕获 ArgumentException,因此它正在等待您在进入最后一个块之前“处理”它。在没有附加调试器的情况下运行您的代码(包括没有您的 JIT 调试器),它应该会命中您的 finally 块。

要禁用 JIT,请转到Options > Tools > Debugging > Just-In-Time并取消选中Managed

要在没有附加调试器的情况下进行调试,请在 Visual Studio 中转到Debug > Start without Debugging(或CTRL + F5

在程序末尾放置一个 Console.ReadLine() 也很有帮助,以防止控制台在进入 finally 块后关闭。

class Program {
    static void Main(string[] args) {
        MyType t = new MyType();
        t.foo();
        Console.ReadLine();
    }
}

这是您应该得到的输出:


抛出 NullReferenceException?ñ

未处理的异常:System.ArgumentException:值不在预期范围内。

在 P:\Documents\Sandbox\Console\Console\Consol e\Program.cs:line 17 中的 ConsoleSandbox.MyType.foo()

在 P:\Documents\Sandbox\Console\Console\Console\Program.cs:line 31 中的 ConsoleSandbox.Program.Main(String[] args)

最后阻止

按任意键继续 。. .

于 2011-02-01T08:41:14.963 回答
1

你看到的是你的测试程序的产物。

如果你改变你的主要方法:

 static void Main(string[] args)
 {
    try
    {
        MyType t = new MyType();
        t.foo();
    }
    catch
    {
       // write something
    }
 }

然后您的foo()行为将按预期进行。

如果没有那个顶级的 try/catch,你的整个程序就会被中止。

于 2011-02-01T08:52:37.090 回答