私のアプリケーションは、データベースからの設定 (ファイル、クラス、およびメソッド名) に基づいて、dll を動的にロードして動作します。リフレクションの使用を容易にし、促進し、減らすために、キャッシュが必要です....
以下を使用するという考えに従ってください:
MethodInfo.Invoke
パフォーマンスは何もありません ( Reflection Performance - Create Delegate (Properties C#) ) メソッドへの呼び出しを翻訳したいと思います。私は次のように機能するものを考えました:
public static T Create<T>(Type type, string methodName) // or
public static T Create<T>(MethodInfo info) // to use like this:
var action = Create<Action<object>>(typeof(Foo), "AnySetValue");
1 つの要件は、すべてのパラメーターをオブジェクトにできることです。
私は式を扱おうとしていますが、これまでのところ次のようなものがあります:
private void Sample()
{
var assembly = Assembly.GetAssembly(typeof(Foo));
Type customType = assembly.GetType("Foo");
var actionMethodInfo = customType.GetMethod("AnyMethod");
var funcMethodInfo = customType.GetMethod("AnyGetString");
var otherActionMethod = customType.GetMethod("AnySetValue");
var otherFuncMethodInfo = customType.GetMethod("OtherGetString");
var foo = Activator.CreateInstance(customType);
var actionAccessor = (Action<object>)BuildSimpleAction(actionMethodInfo);
actionAccessor(foo);
var otherAction = (Action<object, object>)BuildOtherAction(otherActionMethod);
otherAction(foo, string.Empty);
var otherFuncAccessor = (Func<object, object>)BuildFuncAccessor(funcMethodInfo);
otherFuncAccessor(foo);
var funcAccessor = (Func<object,object,object>)BuildOtherFuncAccessor(otherFuncMethodInfo);
funcAccessor(foo, string.Empty);
}
static Action<object> BuildSimpleAction(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
Expression<Action<object>> expr =
Expression.Lambda<Action<object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method), obj);
return expr.Compile();
}
static Func<object, object> BuildFuncAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
Expression<Func<object, object>> expr =
Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method),
typeof(object)),
obj);
return expr.Compile();
}
static Func<object, object, object> BuildOtherFuncAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
Expression<Func<object, object, object>> expr =
Expression.Lambda<Func<object, object, object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj, value);
return expr.Compile();
}
static Action<object, object> BuildOtherAction(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
Expression<Action<object, object>> expr =
Expression.Lambda<Action<object, object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj,
value);
return expr.Compile();
}
public class Foo
{
public void AnyMethod() {}
public void AnySetValue(string value) {}
public string AnyGetString()
{ return string.Empty; }
public string OtherGetString(string value)
{ return string.Empty; }
}
このコードを単純化する方法はありますか? (ジェネリックのみを使用してメソッドを作成することは可能だと思います..)そして、3、4、5、または私のようにパラメーターがある場合はどうなりますか?
私は、次のようなものがあるとしたらどうだろうかと考えていました。
しかし、複数のパラメーター (アクションまたは関数内) があり、このパラメーター (最初のパラメーター) は実行するオブジェクトです。これは可能ですか?