Предположим, у вас есть двоичное представление сигнатуры поля в модуле.NET, например 0604
. 6 (FIELD
) представляет соглашение о вызове поля, а 4 (ELEMENT_TYPE_I1
) представляет собой примитивный тип I1
(подробнее см. ECMA-335 для CIL). Подпись может быть от отладчика или инспектора сборки, что не важно. Что еще более важно, возможно ли (используя методы, предоставленные.NET) "разобрать" эту подпись и получить соответствующий тип.NET, который представляет подпись?
Примеры:
0601
⇒ System.Void
0604
⇒ System.SByte
060E
⇒ System.String
061408020000
⇒ System.Int32[,]
Есть некоторые внутренние методы.NET, которые могут это сделать:
public static unsafe Type GetTypeFromFieldSignature(byte[] signature, Type declaringType = null)
{
declaringType = declaringType ?? typeof(object);
Type sigtype = typeof(Type).Module.GetType("System.Signature");
Type rtype = typeof(Type).Module.GetType("System.RuntimeType");
var ctor = sigtype.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[]{typeof(void*), typeof(int), rtype}, null);
fixed(byte* ptr = signature)
{
object sigobj = ctor.Invoke(new object[]{(IntPtr)ptr, signature.Length, declaringType});
return (Type)sigtype.InvokeMember("FieldType", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, sigobj, null);
}
}
Это загружает любую действительную подпись поля и возвращает соответствующий тип.
Я не знаю ни одного общедоступного API, который может это сделать, но Cecil может анализировать такую подпись внутри, поэтому вы можете скопировать ее код.
Соответствующий код находится в SignatureReader.ReadTypeSignature()
.
Или, может быть, не пытайтесь разбирать сборку самостоятельно и использовать для этого Сесил.