これは、機能に対して直接コード化されます。
public static Assembly LoadAssembly(string assembly, Evidence evidence)
{
Assembly asm;
MethodInfo load =
typeof(Assembly).GetMethod("Load",
new Type[] {typeof(string), typeof(Evidence)});
if (Attribute.IsDefined(load, typeof(ObsoleteAttribute)))
{
asm = Assembly.Load(assembly);
}
else
{
asm = Assembly.Load(assembly, evidence);
}
return asm;
}
このコードは、次の using ステートメントを想定しています。
using System;
using System.Reflection;
using System.Security.Policy;
これが頻繁に呼び出される場合は、このようなものでリフレクション パフォーマンス ヒットを回避できます。
private static bool? _isEvidenceObsolete = null;
public static Assembly AssemblyLoader(string assembly, Evidence evidence)
{
Assembly asm;
if (!_isEvidenceObsolete.HasValue)
{
MethodInfo load =
typeof(Assembly).GetMethod("Load",
new Type[] { typeof(string), typeof(Evidence) });
_isEvidenceObsolete = Attribute.IsDefined(load, typeof(ObsoleteAttribute));
}
if (_isEvidenceObsolete.Value)
{
asm = Assembly.Load(assembly);
}
else
{
asm = Assembly.Load(assembly, evidence);
}
return asm;
}
編集:パフォーマンス統計がどうなるかを自分で確認する必要がありました。これが得られたものです。
経過時間 (ミリ秒):
Catch Exception: 45331
Reflection: 58
Static Reflection: 1
ベンチマークに使用したコードは次のとおりです。
public static void BenchmarkLoaders()
{
Stopwatch timer = new Stopwatch();
// Benchmark catching Exceptions
timer.Start();
for (int i = 0; i < 10000; i++)
{
NotSupported notSupported = new NotSupported();
try
{
notSupported.ThrowException("Obsoleted Method Call");
}
catch (NotSupportedException nse)
{
//Do something
}
}
timer.Stop();
Console.WriteLine("Catch Exception: {0}", timer.ElapsedMilliseconds);
timer.Reset();
// Benchmark Reflection
timer.Start();
for (int i = 0; i < 10000; i++)
{
NotSupported notSupported = new NotSupported();
notSupported.ReflectAssembly();
}
timer.Stop();
Console.WriteLine("Reflection: {0}", timer.ElapsedMilliseconds);
timer.Reset();
// Benchmark Static Reflection
timer.Start();
for (int i = 0; i < 10000; i++)
{
NotSupported.ReflectAssemblyStatic();
}
timer.Stop();
Console.WriteLine("Static Reflection: {0}", timer.ElapsedMilliseconds);
timer.Reset();
}
これがNotSupported
クラスです。
public class NotSupported
{
public void ThrowException(string message)
{
throw new NotSupportedException(message);
}
public void ReflectAssembly()
{
MethodInfo load =
typeof(Assembly).GetMethod("Load",
new Type[] { typeof(string), typeof(Evidence) });
if (Attribute.IsDefined(load, typeof(ObsoleteAttribute)))
{
// Do something
}
}
private static bool? _isEvidenceObsolete = null;
public static void ReflectAssemblyStatic()
{
Assembly asm;
if (!_isEvidenceObsolete.HasValue)
{
MethodInfo load =
typeof(Assembly).GetMethod("Load",
new Type[] { typeof(string), typeof(Evidence) });
_isEvidenceObsolete = Attribute.IsDefined(load, typeof(ObsoleteAttribute));
}
if (_isEvidenceObsolete.Value)
{
//Do Stuff
}
}
}
これらは実際の数値ではないことは承知していますが、例外に対するリフレクションの使用について非常に説得力のある議論を提供します。