.net 什么';这是将状态添加到CLR';什么是动态方法?

.net 什么';这是将状态添加到CLR';什么是动态方法?,.net,clr,code-generation,dynamicmethod,dynamic-method,.net,Clr,Code Generation,Dynamicmethod,Dynamic Method,我正在用DynamicMethod生成一个小代码,我有一个问题可以通过添加一个小状态轻松解决,比如一个字段。不幸的是,我无法将此状态推入该方法的一个参数中,因此我基本上需要关闭一个局部,如以下小lambda: var i = 0; return new Func<int>(() => i++); var i=0; 返回新的Func(()=>i++); 最简单的方法是什么?我相信你不能这么做,至少不能直接这么做DynamicMethod允许您创建单个CLR方法,而不创建其他方

我正在用DynamicMethod生成一个小代码,我有一个问题可以通过添加一个小状态轻松解决,比如一个字段。不幸的是,我无法将此状态推入该方法的一个参数中,因此我基本上需要关闭一个局部,如以下小lambda:

var i = 0;
return new Func<int>(() => i++);
var i=0;
返回新的Func(()=>i++);

最简单的方法是什么?

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

为了实现您想要的,您可以使用动态构建一个带有方法和字段的完整类型

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

Action<TData> CaptureState<TState, TData>(
    Action<TState, TData> originalAction, TState initialState)
{
    var state = initialState;
    return data => originalAction(state, data);
}
动作捕获状态(
动作原始动作,t状态初始状态)
{
var状态=初始状态;
返回数据=>originalAction(状态,数据);
}
然后您可以这样使用它:

Action<State, string> generated = …;
Action<string> captured = CaptureState(generated, new State());
captured("data1");
captured("data2");
生成的操作=…;
捕获的操作=CaptureState(已生成,新状态());
捕获(“数据1”);
捕获(“数据2”);

如果您的方法需要更改状态的值(而不仅仅是修改其中的某些属性),那么您需要为状态使用
ref
参数,但原理是一样的(这也意味着您需要使用自定义委托类型).

+1当您从树中引用对象时,
表达式
API就是这样做的。我希望避免创建新类型和程序集,但这可能是无法避免的。我确实有一种技术滥用泛型为DynamicMethod分配状态。基本上只需生成一个新的嵌套泛型类型并引用一个静态变量: