Почему при создании динамического метода не возникает исключение System.FieldAccessException?

  • 28 августа 2023 г. 3:46
Ответы на вопрос 3
Динамически создаваемые типы и методы, как правило, не вызывают исключение System.FieldAccessException при доступе к их членам, потому что они не имеют ограничений безопасности доступа, как у статических типов и методов.

Чтобы получить доступ к полю "Val" из метода "a()" в типе "DynamicType", вам потребуется использовать методы рефлексии для создания экземпляра типа "DynamicType" и доступа к его полю "Val". Вот пример кода, который демонстрирует, как это сделать:

```csharp
using System;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // Создаем динамическую сборку
        AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
        AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
        
        // Определяем тип DynamicType с полем Val
        TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicType", TypeAttributes.Public);
        FieldBuilder fieldBuilder = typeBuilder.DefineField("Val", typeof(int), FieldAttributes.Public);
        
        // Для простоты, конструктор в типе DynamicType будет устанавливать значение поля Val
        ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(int) });
        ILGenerator constructorIL = constructorBuilder.GetILGenerator();
        constructorIL.Emit(OpCodes.Ldarg_0); // Загружаем ссылку на экземпляр типа на вершину стека
        constructorIL.Emit(OpCodes.Ldarg_1); // Загружаем значение параметра на вершину стека
        constructorIL.Emit(OpCodes.Stfld, fieldBuilder); // Устанавливаем значение поля
        constructorIL.Emit(OpCodes.Ret);
        
        // Создаем тип DynamicType и экземпляр объекта
        Type dynamicType = typeBuilder.CreateType();
        object dynamicObject = Activator.CreateInstance(dynamicType, 42);
        
        // Получаем доступ к полю Val из метода a() и выводим его значение
        MethodInfo aMethod = dynamicType.GetMethod("a");
        aMethod.Invoke(dynamicObject, null);
    }
}
```

Здесь мы создаем динамическую сборку и определяем тип "DynamicType" с публичным полем "Val". При создании экземпляра типа с помощью рефлексии мы передаем значение 42 в качестве аргумента конструктора. Затем мы получаем метод "a()" и вызываем его, что приведет к доступу к полю "Val" и выводу его значения (42) на консоль.

Примечание: рабочий код создает сборку и типы во время выполнения, поэтому это может быть несколько сложнее и менее эффективно по сравнению с компиляцией типов во время проектирования.
Ты редактируешь поле из другой сборки, хотя оно приватное. Возможно, в этом же классе у тебя был делегат для использования метода DynamicMethod. 
 Ты обращаешься к приватному полю из другого проекта. Вероятно, этот же класс содержит делегат для работы с классом DynamicMethod.
Похожие вопросы