.NET Profiler – IMetaDataEmit2::DefineMethodSpec +그 때문에 유용한 도구가 mdv입니다.dotnet/metadata-tools;https://github.com/dotnet/metadata-toolsmdv에서 Generic인자에 관한 테스트를 하고 본 결과, 제네릭 인자에 전달하는 타입마다, 그에 해당하는 MethodSpec을 함께 정의해야 한다는 규칙이 나왔습니다.예를 들면 다음과 같은 제네릭 메서드가 있을 때 static void Invoke존 최(Tobj);T인자에 대해서 다음과 같이 다양한 타입으로 부르면 string text=”TEST”;Invoke(text);//제네릭 매개 변수에 string유형 전달 object obj=new object();Invoke(obj);//제네릭 매개 변수에 object타입 전달 intn=50;Invoke(n);//제네릭 매개 변수가 Int32타입 전달 Programpg=newProgram();//제네릭 매개 변수에 ConsoleApp2.Program전달자 호출마다 MethdoSpec메타 데이터가 개별적으로 추가되는 것을 볼 수 있습니다.TypeDef(0x02):======================================================================================================================================================================================Name Namespace EnclosingType BaseType Interfaces Fields Methods Attributes ClassSize PackingSize======================================================================================================================================================================================1:'<Module>'(#d)nil nil(TypeDef)nil(TypeDef)nil nil nil 0 n/a n/a2:’Program'(#1b5)’ConsoleApp2′(#1)nil(TypeDef)0x0100000f(TypeRef)nil nil 0x06000001-0x06000003 0x00100000(BeforeFieldInit)n/a n/aMethod(0x06,0x1C):====================================================================================================================================================================================================================================================Name Signature RVA Parameters GenericParameters Attributes ImplAttributes ImportAttributes ImportName ImportModule====================================================================================================================================================================================================================================================1:’Main'(#1c4)void(string[])(#3c)0x00002050 0x08000001-0x08000001 nil 0x00000091(PrivateScope, Private, Static, HideBySig)0 0 nil nil(ModuleRef)2:’Invoke'(#18)void(!!0)(#42)0x0000208F 0x08000002-0x08000002 0x2a000001-0x2a000001 0x00000091(PrivateScope, Private, Static, HideBySig)0 0 nil nil(ModuleRef)3:’. ctor'(#1db)void()(#6)0x00002092 nil nil 0x00001886(PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)0 0 nil nil(ModuleRef)MethodSpec(0x2b):========================================Method Signature========================================1:0x06000002(MethodDef)string(#22)2:0x06000002(MethodDef)object(#26)3:0x06000002(MethodDef)int32(#2a)4:0x06000002(MethodDef)ConsoleApp2.Program(#2e)#Blob(size=264):… 그렇긴[생략]···22(MethodSpec):0A-01-0E 26(MethodSpec):0A-01-1C 2a(MethodSpec):0A-01-082e(MethodSpec):0A-01-12-08···[생략]···추가된 MethodSpec의#Blob의 데이터는 다음처럼 해석할 수 있습니다. 0A-01-0E//0A==IMAGE_CEE_CS_CALLCONV_GENERICINST//01==#of generic args//0E==ELEMENT_TYPE_STRING0A-01-1C//0A==IMAGE_CEE_CS_CALLCONV_GENERICINST//0그러기 위해 유용한 도구가 mdv입니다.dotnet/metadata-tools; https://github.com/dotnet/metadata-toolsmdv 에서 Generic 인자에 대한 테스트를 해본 결과 제네릭 인자에게 전달하는 유형별로 그에 해당하는 Method Spec을 함께 정의해야 한다는 규칙이 나왔습니다. 예를 들어 다음과 같은 제네릭 메소드가 있을 때 static void Invoke 정채(Tobj);T인자에 대해 다음과 같이 다양한 타입으로 호출하면 string text=”TEST”; Invoke(text); // 제네릭 파라미터에 string 타입 전달 object obj = new object(); Invoke(obj); // 제네릭 매개변수에 object 유형 전달 intn=50; Invoke(n); // 제네릭 매개변수에 Int32 유형 전달 Programpg=new Program(); // 제네릭 매개변수에 Console App 2. Program 전달자 호출 시마다 MethdoSpec 메타데이터가 개별적으로 추가되는 것을 볼 수 있습니다.TypeDef (0x02):====================================================================================================================================================================================== Name Namespace EnclosingType BaseType Interfaces Fields Methods Attributes ClassSize PackingSize======================================================================================================================================================================================1: ‘<Module>’ (#d) nil nil (TypeDef) nil (TypeDef) nil nil nil 0 n/a n/a2: ‘Program’ (#1b5) ‘ConsoleApp2’ (#1) nil (TypeDef) 0x0100000f (TypeRef) nil nil 0x06000001-0x06000003 0x00100000 (BeforeFieldInit) n/a n/aMethod (0x06, 0x1C):==================================================================================================================================================================================================================================================== Name Signature RVA Parameters GenericParameters Attributes ImplAttributes ImportAttributes ImportName ImportModule====================================================================================================================================================================================================================================================1: ‘Main’ (#1c4) void (string[]) (#3c) 0x00002050 0x08000001-0x08000001 nil 0x00000091 (PrivateScope, Private, Static, HideBySig) 0 0 nil nil (ModuleRef)2: ‘Invoke’ (#18) void (!!0) (#42) 0x0000208F 0x08000002-0x08000002 0x2a000001-0x2a000001 0x00000091 (PrivateScope, Private, Static, HideBySig) 0 0 nil nil (ModuleRef)3: ‘.ctor’ (#1db) void () (#6) 0x00002092 nil nil 0x00001886 (PrivateScope, Public, HideBySig、 SpecialName, RTSpecialName) 0 0 nil nil (ModuleRef)MethodSpec (0x2b):======================================== Method Signature========================================1: 0x06000002 (MethodDef) string (#22)2: 0x06000002 (MethodDef) object (#26) 3: 0x06000002 (Method Def) int32 (#2a) 4: 0x06000002 (Method Def) Console App 2. Program (#2e) #Blob (size = 264): ···[생략]···22 (MethodSpec): 0A-01-0E26 (MethodSpec): 0A-01-1C 2a(MethodSpec): 0A-01-082e(MethodSpec): 0A-01-12-08 == # of generic args // 0E == ELEMENT_TYPE_STRING0A-01-1C // 0A == IMAGE_CEE_CS_CALLCONV_GENERICINST // 0