2012-10-06 8 views
2

DynamicMethod로 약간의 코드 생성을하고 있는데 필드와 같은 작은 상태를 추가하여 손쉽게 해결할 수있는 문제가 있습니다. 불행히도, 난 메서드의 매개 변수 중 하나에이 상태를 밀어 수 없습니다, 그래서 나는 기본적으로이 작은 람다 같은 지역에 걸쳐 닫아야합니다 :CLR의 DynamicMethod에 상태를 추가하는 가장 간단한 방법은 무엇입니까?

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

이 작업을 수행하는 가장 간단한 방법은 무엇입니까?

답변

2

나는 적어도 그렇게 직접 할 수는 없다고 생각합니다. DynamicMethod을 사용하면 단일 CLR 메서드 만 만들 수 있습니다. C# 메서드에는 이러한 제한이 없으므로 클로저 형식과 필드를 자유롭게 만들 수 있습니다.

원하는 것을 얻으려면 TypeBuilder을 사용하여 메서드와 필드로 전체 유형을 동적으로 작성할 수 있습니다.

그러나 더 간단한 옵션은 상태를 매개 변수로 사용하여 메서드를 만든 다음 클로저 (또는 일반 개체)를 사용하여 상태를 캡처하는 것입니다. 뭔가 같은 :

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 매개 변수를 사용해야하지만 원리는 동일하게 작동합니다 (사용자 지정 대리자 형식을 사용해야 함).

+0

+1 'Expression' API는 트리에서 객체를 참조 할 때만 사용됩니다. – usr

+0

새로운 유형과 어셈블리를 만들지 않기를 바랬지 만, 피할 수없는 방법 일 수도 있습니다. DynamicMethod에 상태를 할당하기 위해 제네릭을 남용하는 기술이 있습니다. 기본적으로 새로운 중첩 제네릭 형식을 생성하고 정적 변수를 참조하십시오. http://sasa.hg.sourceforge.net/hgweb/sasa/sasa/file/41094f47bd3d/Sasa/TypeIndexed.cs – naasking