2016-07-15 1 views
0

다음은 샘플 코드를 어떻게 테스트 :Expression.Lamda 동적으로 생성 된 클래스와 함께 작동하지 않습니다

예외

지정 방법은

어떻게

지원되지 않습니다 여기
var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("asm"), AssemblyBuilderAccess.Run); 
var builder = assembly.DefineDynamicModule("MainModule"); 
Type type = builder.DefineType("newType"); 
var parameter = Expression.Parameter(type); 
Console.WriteLine(type); 
var expr = Expression.Lambda(Expression.Constant(1), parameter); 

내가 얻을 나는 그것을 피할 수 있습니까? 이 유형의 컴파일 시간이 없으며 수동으로 방출하는 대신 Expression을 사용하여 생성자를 만들고 싶습니다. 심지어 가능할까요? 인스턴스 메서드로 처리했지만, this을 사용하지 않고 처리했습니다. 이제는 필요하지만, 건설 중에는 금지 된 경우 입력 할 수 있습니다.

+0

당신은'var finalType = builder.CreateType();가 없습니다. [내 질문 [여기] (http://stackoverflow.com/questions/38389479/reflection-emit-throws-badimageformatexception/38389729?noredirect에서보십시오) = 1 # comment64189813_38389729) – lokusking

+0

최종 형식이 아닙니다. 어떻게 클래스를 고정시킨 후에 생성자를 추가 할 수 있습니까? –

+0

새 클래스를 정의한 후에는 올바른 유형을 얻으려면 클래스를 만들어야합니다. 다른 생성자를 추가하려면 다음과 같이하십시오.'builder.DefineConstructor (MethodAttributes.Public, CallingConventions.HasThis, new [] {typeof (string)});'오버로드가 표현식을 허용하지 않습니다. – lokusking

답변

1

글쎄, 이에 대한 우아한 해결 방법을 발견했습니다.

  • 첫째, 우리는 단지 기본 클래스를 만들고, 내 경우에 그것은이었다

    public abstract class AsyncClientBase 
    { 
        protected readonly IAsyncRequestProcessor Processor; 
    
        protected AsyncClientBase(IAsyncRequestProcessor processor) 
        { 
         Processor = processor; 
        } 
    } 
    
  • 그런 다음 우리는 우리의 표현에서 필드를 사용할 수 있습니다 (기본 유형이 때문에 이미 사례).

  • 그런 다음 우리가 통과 PARAMS 생성자 을 (here은 예입니다)
  • 마지막으로, 우리가 T의 기본 유형에 방법에 this 매개 변수의 유형 T을 변경 만들 방출을 사용 (암시 적 변환 아이가있다 - > base이므로 ok입니다.) 생성 된 메소드에서 필드를 사용할 수 있습니다.

Here는 전체 코드가 (ServiceClient, Helpers.XLambdaExpression, Helper.EmitHelper 참조).