Код DynamicMethod не поддается проверке в.Net 4.0 (найден ref 'this' указатель... ожидаемый ref '<>f__AnonymousType1`)
Использовал это решение для преобразования анонимных типов в словари с использованием refle.emit. Работал нормально, пока я не перешел на.Net 4.0 с 3.5.
Теперь я получаю "System.Security.VerificationException: операция может дестабилизировать среду выполнения". ошибка.
Преобразовал анонимно загруженный динамический метод в метод, размещенный в динамической сборке, сохранил его, а затем запустил на нем файл peverify.exe, чтобы выяснить, в чем дело.
Получено: [IL]: Ошибка: [DynamicAssemblyExample.dll: MyDynamicType::MyMethod][offs et 0x0000000D][найдено ref ('this' ptr) 'MyDynamicType'][ожидаемый ref '<>f__AnonymousType1`3[System.String,System.Int32,System.Byte]'] Неожиданный тип в стеке k. [IL]: Ошибка: [DynamicAssemblyExample.dll: MyDynamicType:: MyMethod] [offs et 0x0000000D] Метод не отображается. 2 Ошибка (ы) проверки DynamicAssemblyExample.dll
Код:
foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
{
// load Dictionary (prepare for call later)
methIL.Emit(OpCodes.Ldloc_0);
// load key, i.e. name of the property
methIL.Emit(OpCodes.Ldstr, property.Name);
// load value of property to stack
methIL.Emit(OpCodes.Ldarg_0);
methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
// perform boxing if necessary
if (property.PropertyType.IsValueType)
{
methIL.Emit(OpCodes.Box, property.PropertyType);
}
// stack at this point
// 1. string or null (value)
// 2. string (key)
// 3. dictionary
// ready to call dict.Add(key, value)
methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
}
Есть ли способ разыменовать указатель на фактическое свойство? Или я должен это как-то разыграть? Есть указатели?
С уважением!
2 ответа
Извините, ребята, допустили ошибку, поскольку фактический динамический метод создает тип делегата, который действует на экземпляр анонимного (или неанонимного) типа, код Ldarg_0 ищет что-то, чего нет в этой реализации отладки.
Поэтому я изменил его на OpCodes.Ldnull.
var attributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
{
// load Dictionary (prepare for call later)
methIL.Emit(OpCodes.Ldloc_0);
// load key, i.e. name of the property
methIL.Emit(OpCodes.Ldstr, property.Name);
// load value of property to stack
methIL.Emit(OpCodes.Ldnull);
//methIL.Emit(OpCodes.Castclass, itemType);
methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
// perform boxing if necessary
if (property.PropertyType.IsValueType)
{
methIL.Emit(OpCodes.Box, property.PropertyType);
}
// stack at this point
// 1. string or null (value)
// 2. string (key)
// 3. dictionary
// ready to call dict.Add(key, value)
methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
}
Но я все еще получаю метод не видимой ошибки после его проверки. Неужели методы get для свойств анонимных типов не отображаются через отражение?
Просто предложение, вы пытались переписать код, который испускает IL, чтобы фактически записать в словарь - т.е. нет Reflection.Emit
? Держу пари, что сгенерированный IL каким-то образом неправильный, а не код, который обращается к анонимному типу.