c# – 有没有理由使用Try / Catch与ExceptionThrown变量
我在
.Net Reference Source发现这个宝石,在
ButtonBase.cs在线408:
bool exceptionThrown = true; try { OnClick(); exceptionThrown = false; } finally { if (exceptionThrown) { // Cleanup the buttonbase state SetIsPressed(false); ReleaseMouseCapture(); } } 问题是,什么会激励某人使用exceptionThrowwn标记,只是写它作为 try { OnClick(); } catch { SetIsPressed(false); ReleaseMouseCapture(); throw; } 是只是风格还是有一些副作用我失踪了? 解决方法
这个代码的原因是两倍.是的,格雷格提到,它不需要重新启动异常..但这不是真的原因.
真正的原因是语义之一.异常不应用于处理控制流.这是在处理一个事实,如果一个异常被抛出一个按钮,它可以使按钮视觉状态为“按下”.这不是真的“处理”的例外.这只是在抛出异常的情况下修正视觉问题. 这段代码并不在意什么是异常,它不想捕获所有异常,因为这是不好的做法.此外,代码没有做任何事情的例外..它只是说“嘿,如果我们得到了功能的结束,那么我们都很好,如果我们没有,那么让我们重置按钮状态只是为了确定”. 所以,这不是真正的异常处理,因此它没有捕获异常.它只是注意到抛出异常并进行了一些清理. 编辑: 这种方法可能不那么有争议,如果这样简单地重命名,删除任何对异常的引用,就会更有意义: bool cleanupRequired = true; try { OnClick(); cleanupRequired = false; } finally { if (cleanupRequired) { // Cleanup the buttonbase state SetIsPressed(false); ReleaseMouseCapture(); } } 编辑: 为了支持我的评论,我写了以下测试程序来测试这些场景: static void Main(string[] args) { TimeSpan ts = new TimeSpan(); TimeSpan ts2 = new TimeSpan(); TimeSpan ts3 = new TimeSpan(); TimeSpan ts4 = new TimeSpan(); TimeSpan ts5 = new TimeSpan(); TimeSpan ts6 = new TimeSpan(); TimeSpan ts7 = new TimeSpan(); TimeSpan ts8 = new TimeSpan(); Stopwatch sw = new Stopwatch(); // throw away first run for (int i = 0; i < 2; i++) { sw.Restart(); try { throw new NotImplementedException(); } catch { ts = sw.Elapsed; } sw.Stop(); ts2 = sw.Elapsed; try { sw.Restart(); try { throw new NotImplementedException(); } finally { ts3 = sw.Elapsed; } } catch { ts4 = sw.Elapsed; } sw.Stop(); ts5 = sw.Elapsed; try { sw.Restart(); try { throw new NotImplementedException(); } catch { ts6 = sw.Elapsed; throw; } } catch { ts7 = sw.Elapsed; } sw.Stop(); ts8 = sw.Elapsed; } Console.WriteLine(ts); Console.WriteLine(ts2); Console.WriteLine(ts3); Console.WriteLine(ts4); Console.WriteLine(ts5); Console.WriteLine(ts6); Console.WriteLine(ts7); Console.WriteLine(ts8); Console.ReadLine(); } 我得到以下结果(我把它们分开,使它们更容易阅读): 00:00:00.0028424 00:00:00.0028453 00:00:00.0028354 00:00:00.0028401 00:00:00.0028427 00:00:00.0028404 00:00:00.0057907 00:00:00.0057951 最后3个显示当使用throw重新抛出异常时;它不会简单地传递现有的异常,它必须重新创建异常并重新抛出它,花费两倍的时间. 我们可以看到,捕获异常和捕获之间没有显着差异,而是使用finally.但是,重新开始这个例外就是成本来了. 这在VS 2012 Update 3中运行. 编辑: 没有调试器的时间.正如你所看到的那样,重新开始的价格仍然是两倍: 00:00:00.0000149 00:00:00.0000154 00:00:00.0000137 00:00:00.0000140 00:00:00.0000146 00:00:00.0000137 00:00:00.0000248 00:00:00.0000251 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |