Yes, those methods are pretty much (*) the same. The only difference is that it's easy to put a breakpoint in the first one. I'd always go with the second unless I really needed to break there and only there (as opposed to immediately any exceptions of that type were thrown, which would be easy). Even if I ever used the first, I'd put it back to the second form before committing the code.
(*) There may well be some differences in terms of how the JIT handles them. The first will end up with more IL, which will affect opportunities for inlining etc.
EDIT: I can't resist a bit of micro-benchmarking. It looks like try/catch/throw has nastier effects on performance than just disabling inlining:
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() {}
}
Compile with /o+ /debug-
Results (three runs):
Simple method: 504, 495, 489
No inlining: 2977, 3060, 3019
try/catch/throw: 5274, 4543, 5145