How Do I Create a C# Lambda Expression Programmatically?

Viewed 84

In this example:

    class Example
    {
        public Example()
        {
            DoSomething(() => Callback);                  
        }

        void DoSomething(Expression<Func<Action<string>>> expression) {  }
        void Callback(string s) { }
    }

How do I create () => Callback programmatically, assuming I have its MethodInfo. The debugger shows it as:

{() => Convert(Void Callback(System.String).CreateDelegate(System.Action`1[System.String], value(Example)), Action`1)}

I tried an Expression.Call within an Expression.Convert within an Expression.Lambda, but I can't get the delegate part right.

1 Answers

You can do it like this:

// 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" && 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);
Related