简体   繁体   English

创建使用动态生成类型的表达式树

[英]Creating an expression tree that uses a dynamically generated type

I have a fully initialized MethodBuilder and EnumBuilder . 我有一个完全初始化的MethodBuilderEnumBuilder The MethodBuilder points to the entry point of a dynamic assembly. MethodBuilder指向动态程序集的入口点。 It has the following signature: 它有以下签名:

public static int Main (string [] args) {...}

The assembly generation code works fine and I can use Reflection.Emit to test it. 程序集生成代码工作正常,我可以使用Reflection.Emit来测试它。 Instead of emitting IL, I want to save the target code from an expression tree. 我想要从表达式树中保存目标代码,而不是发出IL。 It should: 这应该:

  • declare a enum variable 声明一个枚举变量
  • assign it a value 为它赋值
  • write to the console 写入控制台
  • read pause the console 读取暂停控制台
  • return a enum value as an Int32 将枚举值作为Int32返回

EXPRESSION TREE: 表达树:

// Intention: Declare string [] args in the expression scope.
var arguments = Expression.Parameter(typeof(string []), "args");
// Intention: var code = default(MyDynamicEnum);
var code = Expression.Variable(builderEnum, "code");
// Intention: code = MyDynamicEnum.Two;
var assign = Expression.Assign(code, Expression.Constant(2, builderEnum));
// Intention: Console.WriteLine(args [0]);
var write = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type [] { typeof(string) }), Expression.ArrayIndex(arguments, Expression.Constant(0, typeof(int))));
// Intention: Console.ReadKey(true);
var read = Expression.Call(typeof(Console).GetMethod("ReadKey", new Type [] { typeof(bool) }), Expression.Constant(true, typeof(bool)));
// Intention: return ((int) code);
var @return = Expression.Constant(2, typeof(int));

// How to combine above expressions and create a function body?
var block = Expression.Block(arguments, code, assign, write, read, @return);
var lambda = Expression.Lambda<Func<string [], int>>(block, new ParameterExpression [] { arguments });

lambda.CompileToMethod(builderMethod); // Error: Variable 'code' of type 'Type: MyDynamicEnum' referenced from scope '', but it is not defined.

The full code is available on this GIST . 完整代码可在此GIST上获得 The error on the last line seems to make sense but I don't know how to fix it. 最后一行的错误似乎有意义,但我不知道如何解决它。 The enumeration MyDynamicEnum is already created as a type but how do I import it into the expression tree context? 枚举MyDynamicEnum已作为类型创建,但如何将其导入表达式树上下文? Any pointers would be appreciated. 任何指针将不胜感激。

Solved it by using the correct overload of Expression.Block . 通过使用Expression.Block的正确重载解决了它。

In order to use variables in the expression scope, we have to specify: 为了在表达式范围中使用变量,我们必须指定:

Expression.Block(variables.ToArray(), queue);

where variables is an array of ParameterExpression types. 其中variables是ParameterExpression类型的数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM