Skip to content

Instantly share code, notes, and snippets.

@dadhi
Created February 15, 2016 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dadhi/ae26182db0dadfe53b62 to your computer and use it in GitHub Desktop.
Save dadhi/ae26182db0dadfe53b62 to your computer and use it in GitHub Desktop.
DynamicMethodFromExpressionWithClosure
using System;
using System.Linq.Expressions;
public class Program
{
public static void Main()
{
var p = new Program();
var expr = p.GetNExpr();
var binExpr = expr.Body as BinaryExpression;
// Console.WriteLine(binExpr);
var xExpr = binExpr.Left as MemberExpression;
//Console.WriteLine(xExpr);
var closureExpr = xExpr.Expression as ConstantExpression;
var closureValue = closureExpr.Value;
//Console.WriteLine(closureValue);
var closureType = xExpr.Member.DeclaringType;
//Console.WriteLine(closureType);
var dynMethod = new System.Reflection.Emit.DynamicMethod(
string.Empty,
typeof(int),
new Type[] { closureType },
closureType,
true);
var il = dynMethod.GetILGenerator();
il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
var xField = closureType.GetField("x");
il.Emit(System.Reflection.Emit.OpCodes.Ldfld, xField);
il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
var yField = closureType.GetField("y");
il.Emit(System.Reflection.Emit.OpCodes.Ldfld, yField);
il.Emit(System.Reflection.Emit.OpCodes.Add);
il.Emit(System.Reflection.Emit.OpCodes.Ret);
var invokeDynMethod = (Func<int>)dynMethod.CreateDelegate(
typeof(Func<int>),
closureValue
);
var sum = invokeDynMethod();
Console.WriteLine(sum);
}
public Expression<Func<int>> GetNExpr() {
var x = 1;
var y = 2;
return () => x + y;
}
int x = 1;
int y = 2;
public int GetN() {
return x + y;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment