向CLR的DynamicMethod添加状态的最简单方法是什么?

时间:2012-10-06 13:53:35

标签: .net clr code-generation dynamicmethod dynamic-method

我正在使用DynamicMethod进行一些代码生成,我遇到了一个问题,可以通过添加一个小的状态(如字段)来轻松解决。不幸的是,我无法将此状态推入方法的参数之一,所以我基本上需要关闭像这个小lambda这样的本地:

var i = 0;
return new Func<int>(() => i++);

最简单的方法是什么?

1 个答案:

答案 0 :(得分:2)

我相信你不能这样做,至少不是直接的。 DynamicMethod允许您创建单个CLR方法而不创建任何其他方法。 C#方法没有这个限制,他们可以自由地在其中创建闭包类型和字段以及他们需要的任何其他内容。

要实现您的目标,您可以使用TypeBuilder动态构建包含方法和字段的完整类型。

但更简单的选择是使用state作为参数创建方法,然后使用闭包(或者,普通对象)来捕获状态。类似的东西:

Action<TData> CaptureState<TState, TData>(
    Action<TState, TData> originalAction, TState initialState)
{
    var state = initialState;
    return data => originalAction(state, data);
}

然后你会像这样使用它:

Action<State, string> generated = …;
Action<string> captured = CaptureState(generated, new State());
captured("data1");
captured("data2");

如果您的方法需要更改状态的值(而不仅仅是修改它的某些属性),那么您需要对状态使用ref参数,但原理的作用相同(它会也意味着你需要使用自定义委托类型。)