Try-Catch-Finally阻止了.NET4.5.1的问题

时间:2015-06-16 21:15:45

标签: c#

我有一个简单的测试代码,可以在.NET3.5中按预期工作,但在使用.NET4.5.1创建的项目中,相同的代码表现完全不同。

class Program
{
    static void Main(string[] args)
    {
        try
        {
            string a = null;
            var x = a.Length;
        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            Console.WriteLine("This is the finally block.");
        }
        Console.WriteLine("You should not be here if an exception occured!");
    }
}

首先,奇怪的是,在运行已编译的RELEASE exe文件时,.NET4.5.1中完全忽略了NullReferenceException类型异常。基本上,不会抛出任何错误,但在调试模式下会抛出异常。

其次(最重要的是),如果错误与NullReferenceException不同,例如“索引超出范围”,则实际上会按预期抛出异常,但是“finally”块永远不会被命中不是我期望从try-catch-finally块中获得的行为。我尝试了不同的机器,并且我的其他两位同事也在尝试,我们都得到了相同的结果。

似乎我从未真正理解try-catch-finally块,或者.NET4.5.1以不同的方式处理异常,或者.NET4.5.1存在一些错误。我所知道的是上面的代码在.NET3.5中工作,正如我所期望的那样,但是在.NET4.5.1中运行它时似乎没有得到相同的结果。

有人可以对此有所了解吗?我现在完全失去了。

修改 根据Eric J的回答,我能够解决NullReferenceException问题。自从我提出两个问题后,我将为第二个问题创建一个新线程。 Try-Catch-Finally block problems with .NET4.5.1

1 个答案:

答案 0 :(得分:22)

string a = null;
var x = a.Length;

在RELEASE模式下,抖动(即时编译器)能够证明x从未被引用,因此可以删除赋值。

在DEBUG模式下,抖动不会执行该优化。

要强制抛出异常,请使用x执行某些操作(例如@Henk在评论中建议WriteLine(x))。

修改

Eric Lippert在评论中指出

  

......我和任何人一样惊讶于抖动会消除一根弦   可以抛出的长度指令。这对我来说似乎不对......

抖动优化可能过于激进。