这段代码的原因有两个。是的,格雷格提到,它不需要重新抛出异常......但这并不是真正的原因。
真正的原因是语义之一。不应使用异常来处理控制流。这样做是为了处理这样一个事实,即如果在按钮内引发异常,它可以将按钮的视觉状态保持为“按下”。这并不是真正“处理”异常。这只是在抛出异常时纠正视觉问题。
这段代码不关心异常是什么,也不想捕获所有异常,因为这是不好的做法。此外,代码没有做任何异常......它只是说“嘿,如果我们到达函数的末尾,那么我们都很好。如果我们没有,那么让我们重置按钮状态只是为了确定”。
因此,这不是真正的异常处理,因此它不会捕获异常。它只是注意到引发了异常并进行了一些清理。
编辑:
这种方法可能争议较小,如果像这样简单地重命名它,删除对异常的任何引用,则更有意义:
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