2

I'm doing a little code generation with DynamicMethod and I have a problem that would be handily solved by adding a little state, like a field. Unfortunately, I can't push this state into one of the method's parameters, so I basically need to close over a local like this little lambda:

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

What's the simplest way to do this?

svick
  • 236,525
  • 50
  • 385
  • 514
naasking
  • 2,514
  • 1
  • 27
  • 32

1 Answers1

2

I believe you can't do that, at least not directly. DynamicMethod lets you create a single CLR method and nothing else. C# methods don't have that limitation, they are free to create closure types and fields in them and whatever else they need.

To achieve what you want, you could use TypeBuilder to dynamically build a full type with a method and a field.

But a simpler option would be to create the method with the state as a parameter and then use a closure (or, alternatively, a normal object) to capture the state. Something like:

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

You would then use it like this:

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

If your method needs to change the value of the state (and not just modify some properties on it), then you would need to use ref parameter for the state, but the principle works the same (it would also mean you would need to use custom delegate type).

svick
  • 236,525
  • 50
  • 385
  • 514
  • +1 The `Expression` API does just that when you reference an object from a tree. – usr Oct 06 '12 at 16:17
  • I was hoping to avoid the creation of new types and assemblies, but perhaps it's not avoidable. I do have a technique that abuses generics to allocate state for a DynamicMethod. Basically just generate a new nested generic type and reference a static variable: http://sasa.hg.sourceforge.net/hgweb/sasa/sasa/file/41094f47bd3d/Sasa/TypeIndexed.cs – naasking Oct 07 '12 at 14:17