많은 MSIL 목록에서 다음을 관찰했습니다.
System.Nullable`1<!0> etc ...
또는
class !0 etc ...
!0
이러한 상황에서 의 의미는 무엇입니까 ?
답변:
이것은 .NET 어셈블리를 보는 데 사용하는 디 컴파일러의 특징입니다. 그것은 ildasm.exe의 동작이며, Reflector 또는 ILSpy와 같은 다른 사람들이이 문제를 해결합니다. 이를 작성한 Microsoft 프로그래머는 바로 가기 를 사용하여 메타 데이터에서 형식 인수 이름을 조회하는 추가 코드를 작성하지 않고 인코딩 된 방식으로 형식 인수를 표시하는 문자열을 IL에서 생성합니다 .
!n
제네릭 유형의 n 번째 유형 인수 로 읽어야 합니다. 여기서! 0은 "첫 번째 유형 인수",! 1은 "두 번째 유형 인수"등을 의미합니다. Nullable <>의 경우 MSDN 기사에서 '! 0'은 'T'를 의미합니다.
또한 !!T
. 두 개의 느낌표는 제네릭 메서드에 대한 형식 인수를 나타냅니다 . 이번에는 ildasm.exe와는 않습니다 사용하는 대신 형식 인수의 이름을 조회 !!0
. 프로그래머가 제네릭 유형에 대한 지름길을 선택했지만 제네릭 메서드에는 적용하지 않는 이유는 리버스 엔지니어링하기 어렵습니다. Ildasm은 매우 기발한 프로그램이며 .NET의 다른 C ++ 코드와는 매우 다른 C ++ 코딩 스타일로 작성되었습니다. 이것이 인턴의 임무 였을 확률이 0이 아닌, 훈련되지 않았습니다. :)
"Nullable"의`1 접미사는 일반 유형 이름에 대한 일반 인코딩이며, 일반 유형에 하나의 유형 인수가 있음을 나타냅니다. 즉, Nullable <>의 경우! 1이 사용되는 것을 볼 수 없습니다.
그래서 단순히 !0
"T"로 읽으십시오 . 또는 더 나은 디 컴파일러를 사용하십시오.
이는 일반 유형 매개 변수입니다.
그들은 위치 적입니다.
일반 코드를 디 컴파일하여 사용 방법을 확인합니다 (IL과 C # 비교).
ldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionary
하거나 call instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool)
. 어쨌든 원시 IL은 위치 인수 만 사용하지만 !TKey
이미 IL을 더 읽기 쉽게 만들려는 시도입니다. 항상 잘 작동하지 않을 수도 있습니다. ECMA 사양은 항상 위치 !0
/ !00
도 사용합니다 .
!T
및!!T
일반 매개 변수를 포함하는 클래스의 또는 방법의 경우 내가 ILDASM 사용하는 경우 같은 ... 따라