2009-10-20 3 views
3

일부 유형을 동적으로 생성해야합니다. 생성 된 유형에는 여러 가지 메소드, 생성자가 있으며 인터페이스를 구현하고 정적 생성자를 정의합니다. 작업에 도움이되는 도구가 있습니까?Reflection.Emit을 사용하여 작업을 쉽게 할 수있는 도구가 있습니까?

리플 렉터를위한 this 플러그인을 알고 있지만 아직 전체 유형을 생성해야하지만 메소드 레벨에서만 유용합니다.

Run#이 있지만 사전 알파에 있지만 오프라인 모드에서 독립 실행 형 도구를 사용하여 reflection.emit 지침을 프로덕션 코드에 복사하여 붙여 넣을 수 있습니다.

답변

2

예!

원시 IL 대신 추상 표현 트리를 사용하여 코드 생성을 크게 단순화하는 System.Linq.Expressions 네임 스페이스 (.NET 3.5)가 있습니다. 당신은 것입니다, 당신은 전체 클래스를 만들려면, 그래서 당신은,하지만 단지 기능 유형을 만들 수 없습니다

ParameterExpression numParam = Expression.Parameter(typeof(int), "num"); 
ConstantExpression five = Expression.Constant(5, typeof(int)); 
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five); 
Expression<Func<int, bool>> lambda1 = 
    Expression.Lambda<Func<int, bool>>(
     numLessThanFive, 
     new ParameterExpression[] { numParam }); 

: 여기

난 그냥 그 힘을 보여주기 위해 MSDN Expression Trees page에서 도난 한 예입니다 불행히도 이것을 Reflection.Emit과 결합해야합니다.

+1

이것을 Reflection.Emit과 결합 할 수 있습니까? – SLaks

+0

SLaks : 예, 예를 들어, Reflection.Emit에서 유형을 생성하고 MethodBuilder를 사용하여 메소드를 작성한 다음 메소드의 ILGenerator를 사용하여 컴파일 된 표현식 트리를 호출 할 수 있습니다. 이를 수행하는 간단한 방법이있을 수 있지만 이는 효과가 있습니다. –

3

글쎄, 개인적으로 항상 적절한 매개 변수를 사용하여 opcode와 동일한 이름을 가진 ILGenerator 클래스의 확장 메소드를 만들었으므로 항상 문서를 조회 할 필요가 없습니다. 이러한 확장 메서드는 호출 된 생성기 개체도 반환하므로 호출 체인을 수행 할 수 있습니다.

예를 들어, ToString 메서드를 구현하기 위해, 나는이 작업을 수행 할 수 있습니다 :

var il = method.GetILGenerator(); 
il 
    .ldarg_0() 
    .ldfld(nameField) 
    .ret(); 

나는 또한 IL.Element 개체를 반환 방법을 가지고 IL라는 이름의 유사한 클래스를, 만든 어떤 I 마침내 코드를 방출하기 전에 콜렉션 또는 유사한 것으로 수집하여 조작 할 수 있습니다. 이를 통해 "코드 생성자"뿐만 아니라 "코드 생성자"를 만들 수 있습니다. 미묘한 차이가 있지만, "내가 낼 수있는 코드를 내게주세요"라는 것이 "이 ILGenerator에 코드를 내 보냅니다"보다 유용하다는 것을 알았습니다. 따라서

, 나는이 작업을 수행 할 수 있습니다 : 다음

IL.Element[] il = new IL.Element[] { 
    IL.ldarg_0(), 
    IL.ldfld(nameField), 
    IL.ret() 
}; 

과 :

method.GetILGenerator.Emit(il); // also an extension method 

은 물론, 나는 나뿐만 아니라 코드를 방출하는 것이 쉽게 몇 가지 추가 확장 메서드를 추가했습니다 "call_smart"와 같이 메소드의 유형 (정적, 가상 등)을 기반으로 방출 할 호출 명령어를 결정합니다.

그 외의 다른 도구에 대해서는 알지 못해서 아마도 귀하의 질문에 답변하지 못했을 것입니다.

The code is available on CodePlex.

+0

감사합니다. 그러나 귀하의 사례는 귀하가 일리노이에 대해 잘 알고 있음을 보여줍니다. 이것은 확장 메소드의 API에 반영됩니다. 나는 일리노이를 잘 통제하지 못한다. 리플 렉터에 대한 Reflection.Emit 플러그인과 같은 상위 레벨의 것이 필요합니다 (스테로이드 사용). – mark

+1

아, 알겠습니다. 죄송합니다. 거기서 도울 수는 없지만 .NET 4.0의 Expression 지원을 살펴보십시오. 3.5에서는 생성 할 수있는 것에 국한되지만 4.0에서는 거의 모든 종류의 코드를 작성할 수 있도록 클래스가 업데이트되었습니다. –

+0

또한, 나는 좋은 책을 추천 할 수있다 : Expert IL Assembler 2.0 (http://www.amazon.com/Expert-NET-2-0-IL-Assembler/dp/1590596463). –

관련 문제