Как мне создать лямбда-выражение C # программно?

#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);