Код DynamicMethod не поддается проверке в .Net 4.0 (найден ref 'this' указатель ... ожидается ref '<> f__AnonymousType1`) - PullRequest
1 голос
/ 06 июля 2010

Использовал это решение для преобразования анонимных типов в словари с использованием refle.emit. Работал нормально, пока я не перешел на .Net 4.0 с 3.5.

Теперь я получаю «System.Security.VerificationException: операция может дестабилизировать среду выполнения». ошибка.

Преобразует анонимно загруженный динамический метод в метод, размещенный в динамической сборке, сохраняет его, а затем запускает на нем файл peverify.exe, чтобы выяснить, в чем дело.

Получил: [IL]: Ошибка: [DynamicAssemblyExample.dll: MyDynamicType :: MyMethod] [offs et 0x0000000D] [found ref ('this' ptr) 'MyDynamicType'] [ожидаемый ref '<> f__AnonymousType1`3 [System.String, System.Int32, System.Byte]'] Неожиданный тип в stac к. [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 ]

0 голосов
/ 06 июля 2010

Просто предложение, вы пытались переписать код, который генерирует IL, для фактической записи в словарь - т.е. нет Reflection.Emit? Держу пари, что сгенерированный IL каким-то образом неправильный, а не код, который обращается к анонимному типу.

0 голосов
/ 06 июля 2010

Извините, ребята, допустили ошибку, поскольку фактический динамический метод создает тип делегата, который действует на экземпляр анонимного (или неанонимного) типа, код 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 для свойств анонимных типов не видны через отражение?

...