Ja, diese Methoden sind so ziemlich (*) die gleichen. Der einzige Unterschied ist, dass man bei der ersten Methode leicht einen Haltepunkt setzen kann. Ich würde mich immer für die zweite entscheiden, es sei denn, ich muss dort und nur dort unterbrechen (im Gegensatz zu sofortigen Ausnahmen dieses Typs, was einfach wäre). Selbst wenn ich jemals die erste Form verwenden würde, würde ich sie in die zweite Form zurücksetzen, bevor ich den Code festlege.
(*) Es kann durchaus Unterschiede in der Art und Weise geben, wie der JIT sie behandelt. Die erste Variante wird mehr AWL enthalten, was sich auf die Möglichkeiten des Inlinings usw. auswirkt.
EDIT: Ich kann nicht widerstehen, ein bisschen Micro-Benchmarking. Es sieht aus wie try/catch/throw hat böser Auswirkungen auf die Leistung als nur deaktivieren 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() {}
}
Kompilieren mit /o+ /debug-
Ergebnisse (drei Durchläufe):
Einfache Methode: 504, 495, 489
Kein Inlining: 2977, 3060, 3019
try/catch/throw: 5274, 4543, 5145