How does one generate delegates using Expressions?

Mar 27, 2010 at 4:37 AM

I am trying to use Expressions to generate dynamic code to assembly. The goal is to provide maximum application performance by avoiding dynamic compilation, which, given the scale of the generated code, can take upto half a minute. A key part of this process is that I also need to emit expressions to create various data structures, some of which contain delegates to the generated methods. However, unlike in IL, there doesn't seem to be any way to do this. Reflectively creating delegates after assembly load is not ideal. Can anyone help? Am I missing something?

A simplified example of what I'm trying to achieve (in c# syntax) is :

public class DataClass

{

 public MethdInvoker TheMethodForThisObject;

}

 

public static class Generated{ //this class is generated in a dynamic assembly

public static void Main(){

DataClass obj=new DataClass();

obj.TheMethodForThisObject=Method1;

}

public static void Method1(){

}

}

Coordinator
Mar 31, 2010 at 2:02 AM

You need to create the outer lambda (Main) and then compile that using a method builder.  The outer lambda can contain a reference to an inner lambda (Method1) and use that lambda in an assignment statement which will create the delegate instance for you.  This will work great as long as you don’t need to call the inner lambda anywhere else.  Here’s a sample which does this:

public class DataClass {

        public Action TheMethodForThisObject;

    }

    class Foo {

        public static void Main(string[] args) {

            var param = Expression.Parameter(typeof(DataClass), "obj");

            var outerLambda = Expression.Lambda<Action>(

                Expression.Block(

                    new[] { param },

                    Expression.Assign(param, Expression.New(typeof(DataClass))),

                    Expression.Assign(

                        Expression.Field(param, "TheMethodForThisObject"),

                        Expression.Lambda<Action>(

                            Expression.Empty()

                        )

                    )

                ),

                "Main",

                new ParameterExpression[0]

            );

            var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("test.dll"), System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave);

            var module = asm.DefineDynamicModule("test", "test.dll");

            var type = module.DefineType("Generated", TypeAttributes.Public);

            var method = type.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static);

            outerLambda.CompileToMethod(method);           

           

            type.CreateType();

            asm.Save("test.dll");          

        }

    }

}

From: ctimmings [mailto:notifications@codeplex.com]
Sent: Friday, March 26, 2010 9:37 PM
To: Dino Viehland
Subject: How does one generate delegates using Expressions? [dlr:207489]

From: ctimmings

I am trying to use Expressions to generate dynamic code to assembly. The goal is to provide maximum application performance by avoiding dynamic compilation, which, given the scale of the generated code, can take upto half a minute. A key part of this process is that I also need to emit expressions to create various data structures, some of which contain delegates to the generated methods. However, unlike in IL, there doesn't seem to be any way to do this. Reflectively creating delegates after assembly load is not ideal. Can anyone help? Am I missing something?

A simplified example of what I'm trying to achieve (in c# syntax) is :

public class DataClass

{

public MethdInvoker TheMethodForThisObject;

}

public static class Generated{ //this class is generated in a dynamic assembly

public static void Main(){

DataClass obj=new DataClass();

obj.TheMethodForThisObject=Method1;

}

public static void Method1(){

}

}

Read the full discussion online.

To add a post to this discussion, reply to this email (dlr@discussions.codeplex.com)

To start a new discussion for this project, email dlr@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com