Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.07.2010, 20:27   #1
adwaer
Пользователь
 
Регистрация: 06.06.2008
Сообщений: 47
По умолчанию System.Reflection.Emit -> конструктор неправильный

Мне необходимо налету создать класс, проинициализировать поля (значения приходят) и поместить этот класс в PropertyGrid.
Вот процедура которая создает класс. Ошибка в конструкторе.. Помогите пожалуйста, нужно проинициализировать в конструктор все создаваемые в "foreach" поля

Код:
// Создаём сборку
            AppDomain Domain = System.Threading.Thread.GetDomain();
            AssemblyName AsmName = new AssemblyName();
            AsmName.Name = "DynamicAssembly";
 
            // To generate a persistable assembly, specify AssemblyBuilderAccess.RunAndSave.
            AssemblyBuilder AsmBuilder = Domain.DefineDynamicAssembly(AsmName,
                                                            AssemblyBuilderAccess.RunAndSave, @"c:\");//Path.GetTempPath());
 
            // Generate a persistable single-module assembly.
            ModuleBuilder ModBuilder =
                AsmBuilder.DefineDynamicModule(AsmName.Name, AsmName.Name + ".dll");
 
 
            // Прокси-класс
            TypeBuilder TypeBuilder = ModBuilder.DefineType("PropertyClass", TypeAttributes.Public | TypeAttributes.Class);
 
            List<Type> ctorParams = new List<Type>();
            List<FieldBuilder> fields = new List<FieldBuilder>();
 
            foreach (RParam param in args)
            {
                ctorParams.Add(param.RType);
                //Приватное поле
                FieldBuilder FieldBldr = TypeBuilder.DefineField(param.Name.ToLower(),
                                                            param.RType,
                                                            FieldAttributes.Private);
                fields.Add(FieldBldr);
                
                //Свойство
                PropertyBuilder PropertyBldr = TypeBuilder.DefineProperty(param.Name,
                                                             PropertyAttributes.HasDefault,
                                                             param.RType,//typeof(String),
                                                             null);
                //Атрибуты Геттера
                MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName |
                                                MethodAttributes.HideBySig;
                // Геттер
                MethodBuilder Get = TypeBuilder.DefineMethod("Get_" + param.Name, getSetAttr,
                                                                typeof(string), Type.EmptyTypes);
                ILGenerator GetFld = Get.GetILGenerator();
                GetFld.Emit(OpCodes.Ldarg_0);
                GetFld.Emit(OpCodes.Ldfld, FieldBldr);
                GetFld.Emit(OpCodes.Ret);
 
                //Сеттер
                MethodBuilder Set = TypeBuilder.DefineMethod("Set_" + param.Name,
                                                                    getSetAttr, null,
                                                                    new Type[] { param.RType });
                ILGenerator SetFld = Set.GetILGenerator();
 
                SetFld.Emit(OpCodes.Ldarg_0);
                SetFld.Emit(OpCodes.Ldarg_1);
                SetFld.Emit(OpCodes.Stfld, FieldBldr);
                SetFld.Emit(OpCodes.Ret);
 
                PropertyBldr.SetGetMethod(Get);
                PropertyBldr.SetSetMethod(Set);
            }
 
            // Конструктор прокси-класса.
            ConstructorBuilder pointCtor = TypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams.ToArray());
            ILGenerator ilgen = pointCtor.GetILGenerator();
 
            ILGenerator ctorIL = pointCtor.GetILGenerator();
            ctorIL.Emit(OpCodes.Ldarg_0);
            ctorIL.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0]));
            ctorIL.Emit(OpCodes.Ret);
 
 
            Type type = TypeBuilder.CreateType();
            return Activator.CreateInstance(type, new object[] {  });
adwaer вне форума Ответить с цитированием
Старый 14.07.2010, 20:50   #2
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Обязательно использовать CIL ? Гораздо проще на лету написать и скомпилировать код C#

Код:
using System;
using System.Reflection;
using System.CodeDom.Compiler;

namespace test
{
    class Program
    {
        static void Main()
        {

            CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
            Console.WriteLine(provider);

            String[] referenceAssemblies = { "System.dll" };
            CompilerParameters param = new CompilerParameters(
                referenceAssemblies,  // Подключаемые сборки 
                @"D:\test.dll",       // имя файла
                false);               // без отладочной информации
            param.GenerateInMemory = true;

            CompilerResults res = provider.CompileAssemblyFromSource(
                param,
                "using System;" +
                "namespace MNameSpace" +
                "{" +
                "   class MyClass" +
                "   {" +
                "       public MyClass()" +
                "       {" +
                "           Console.WriteLine(\"MyClass.Create\");" +
                "       }" +
                "   }" +
                "}"
            );

            if (res.Errors.Count > 0)
            {
                foreach (CompilerError s in res.Errors)
                {
                    Console.WriteLine(s.ToString());
                }
            }

            Assembly a = res.CompiledAssembly;

            // Теперь у нас есть сборка 
            // Дальше обычное использование класса 
            Type t = a.GetType("MNameSpace.MyClass");
            object c = Activator.CreateInstance(t);
alexBlack вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
неправильный user32.lib 547538594554849886 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 5 22.12.2009 21:27
неправильный запрос? dedyshka PHP 8 17.11.2009 20:27
C# Reflection: разблокировать файл после LoadAssembly Hollander Общие вопросы .NET 4 23.01.2009 16:24
Программа строит неправильный график xMass Помощь студентам 7 06.06.2008 19:04
Неправильный вывод данных из стека С++ Cyberex Общие вопросы C/C++ 3 07.05.2008 16:53