2010-02-08 5 views
2

나는 런타임시 내 자신의 함수를 Reflection.Emit으로 작성하여 CIL을 배우고있다. 나는 실제로 지금까지 얼마나 쉬운 일들이 있었는지에 놀랐지 만 나는 내 방식으로는 추측 할 수없는 뭔가를 치고 문서에서 상대적인 것을 찾을 수는 없다.내 자신의 클래스 인스턴스로 DynamicMethod를 호출하면 예외가 발생하는 이유는 무엇입니까?

내가 정의한 매우 간단한 클래스를 단순히 인쇄하는 함수를 만들려고합니다. string을 인쇄하기 위해 코드를 변경한다고해도 작동하지만, 클래스 A 클래스의 인스턴스를 전달하면 항상 실행되지 않습니다.

무엇이 이상한가요? 내 기능 본문을 주석 처리 할 수 ​​있으며 여전히 TargetInvocationException으로 실패합니다. 그것은 아주 간단해야하지만 나는 무엇이 일어나는지 볼 수 없다!

class A 
{ 
    public override string ToString() 
    { 
     return "AAA!"; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     DynamicMethod func = new DynamicMethod("func", null, new Type[] { typeof(A) }); 

     ILGenerator il = func.GetILGenerator(); 

     //il.Emit(OpCodes.Ldarg_0); 
     //il.Emit(OpCodes.Box, typeof(A)); 
     //il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(A) })); 

     il.Emit(OpCodes.Ret); 

     func.Invoke(null, new object[] { new A() }); 

     Console.Read(); 
    } 
} 

나는이 예외를 발생시킬 수 있도록 그래서 무슨 일을하고 있는가? 왜 이것이 내 수업에서만 일어나는가?

답변

0

문제는 간단하지만 분명하지 않습니다. 시작을 위해 이미 지적 된대로 인수를 상자에 넣지 마십시오. 하지만 진짜 문제는 A 클래스가 공개되지 않는다는 것입니다. 사용중인 Invoke 함수의 기본 바인딩은 전체 메서드가 아닌 public 메서드를 찾는 것입니다. A는 비공개 클래스이기 때문에 함수를 찾지 못하고 (놀랍지 만), 실패합니다.

+0

나는 당신이 게시 한대로 거의 깨달았다. 그러므로 제 대답은 같은 줄에 있습니다. 이것은 정답입니다! –

+0

가끔 반성을 좋아해야합니다. 특히 당신이 객체 나 문자열을 시도 할 때, 당신이 합리적인 답변을 줄 수는 없으며 단지 공개이기 때문에 작동합니다. grr :) – tyranid

0

첫 번째 - A이 클래스이므로 박스 처리 할 필요가 없으므로 Box 작동 코드를 방출하면 안됩니다. 권투는 가치 유형에만 해당됩니다.

두 번째 - 실패하는 이유는 메서드에 클래스 A에 액세스 할 수있는 권한이 없기 때문입니다 (공용이 아닙니다). 어느 쪽이든 Apublic 또는 this constructor을 사용하고 true을 skipVisibility 매개 변수에 전달하여 가시성 검사를 건너 뛰도록 JIT 컴파일러에 지시 할 수 있습니다.

+0

줄을 주석 처리하더라도 예외가 발생합니다. –

+0

나는 이것이 실패한 진짜 이유를 포함하도록 나의 응답을 편집했다. –

1

실제로 매우 바보 같았습니다. 나는 이것에 대해 몇 시간을 보냈지 만 Laurent Etiemble의 조언을 따르고 대의원을 만들었을 때 예외는 아니었다. 내 수업 A가 공개되지 않았다는 말을 들었다.

해결책 : class A 앞에 public 키워드를 추가하십시오. 완벽하게 작동합니다. 나는 을 알았고은 미친 듯이 간단해야했습니다.