是的,这些方法几乎 (*) 相同。唯一的区别是在第一个断点很容易。我总是选择第二个,除非我真的需要在那里打破并且只在那里(而不是立即抛出任何那种类型的异常,这很容易)。即使我曾经使用过第一种形式,我也会在提交代码之前将其放回第二种形式。
(*) JIT 处理它们的方式可能存在一些差异。第一个最终会得到更多的 IL,这将影响内联等的机会。
编辑:我无法抗拒一些微基准测试。看起来 try/catch/throw 对性能的影响比仅仅禁用内联更严重:
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
public class Test
{
const int Iterations = 1000000000;
static void Main()
{
Stopwatch sw;
sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
SimpleMethod();
}
sw.Stop();
Console.WriteLine("Simple method: {0}", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
NoInlining();
}
sw.Stop();
Console.WriteLine("No inlining: {0}", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
TryCatchThrow();
}
sw.Stop();
Console.WriteLine("try/catch/throw: {0}", sw.ElapsedMilliseconds);
}
static void SimpleMethod()
{
Foo();
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void NoInlining()
{
}
static void TryCatchThrow()
{
try
{
Foo();
}
catch (Exception)
{
throw;
}
}
static void Foo() {}
}
编译/o+ /debug-
结果(三轮):
简单方法:504、495、489
无内联:2977、3060、3019
try/catch/throw:5274、4543、5145