#c# #.net #linq #lambda
#c# #.net #linq #лямбда
Вопрос:
В этом примере:
class Example
{
public Example()
{
DoSomething(() => Callback);
}
void DoSomething(Expression<Func<Action<string>>> expression) { }
void Callback(string s) { }
}
Как мне создать () => Callback
программно, предполагая, что у меня есть его MethodInfo. Отладчик отображает его как:
{() => Convert(Void Callback(System.String).CreateDelegate(System.Action`1[System.String], value(Example)), Action`1)}
Я попробовал Expression.Call
внутри Expression.Convert
внутри Expression.Lambda
внутри, но я не могу получить правильную часть делегирования.
Ответ №1:
Вы можете сделать это следующим образом:
// obtain Example.Callback method info
var callbackMethod = this.GetType().GetMethod("Callback", BindingFlags.Instance | BindingFlags.NonPublic);
// obtain Delegate.CreateDelegate _instance_ method which accepts as argument type of delegate and target object
var createDelegateMethod = typeof(MethodInfo).GetMethods(BindingFlags.Instance | BindingFlags.Public).First(c => c.Name == "CreateDelegate" amp;amp; c.GetParameters().Length == 2);
// create expression - call callbackMethod.CreateDelegate(typeof(Action<string>), this)
var createDelegateExp = Expression.Call(Expression.Constant(callbackMethod), createDelegateMethod, Expression.Constant(typeof(Action<string>)), Expression.Constant(this));
// the return type of previous expression is Delegate, but we need Action<string>, so convert
var convert = Expression.Convert(createDelegateExp, typeof(Action<string>));
var result = Expression.Lambda<Func<Action<string>>>(convert);