2014-11-29 3 views
1

Предположим, что у вас есть двоичное представление сигнатуры поля в модуле .NET, например 0604. 6 (FIELD) представляет собой соглашение о полевых вызовах, а 4 (ELEMENT_TYPE_I1) представляет примитивный тип I1 (см. ECMA-335 для получения дополнительной информации о CIL). Подпись может быть от отладчика или инспектора сборки, что не важно. Что еще более важно, возможно ли (используя методы, предоставленные .NET) «разобрать» эту подпись и получить соответствующий тип .NET, который представляет подпись?Получить тип, сохраненный в двоичной сигнатуре поля

Примеры:

0601System.Void
0604System.SByte
060ESystem.String
061408020000System.Int32[,]

ответ

0

Есть некоторые внутренние .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); 
    } 
} 

Это загружает любую правильную подпись поля и возвращает соответствующий тип.

1

Я не знаю, о каком-либо общественном API, который может это сделать, но Cecil может разобрать этот вид подписи внутри, чтобы вы могли скопировать его код.

Соответствующий код находится в SignatureReader.ReadTypeSignature().

Или, может быть, не пытайтесь разобрать сборку самостоятельно и использовать для этого Сесил.