How use Dynamic created class in List

2019-08-25 02:14发布

I'm working on Dynamic Runtime C# class it creates it good but I can't use it in List<T> and this Student class can not get new from it. I want to add it in an array of entities and it doesn't work.

CType.MyClassBuilder MCB = new CType.MyClassBuilder("Student");
    //dynamic myclass = MCB.CreateObject(new string[3] { "ID", "Name", "Address" }, new Type[3] { typeof(int), typeof(string), typeof(string) });
    var myclass = MCB.CreateObject(prop.ToArray(), typelist.ToArray());
    //myclass.
    // Type sw=Type.GetType(myclass);
    //  var ooo=new List<myclass.>();
    Type tp = myclass.GetType();
    var sq=new Hashtable();
    Student s1=new Student();
    var tclass=myclass;
    // tp instance = (tp)Activator.CreateInstance(tp);
    var s = new ArrayList();
    var w=new List<po>();
    myclass.GetType();
    for (int i = 0; i < 10; i++) {
        myclass.GetType().GetProperty("id").SetValue(myclass,i);
        // sq.Add(i,new (object(myclass)));
        sq.Add(i,myclass);
    }
}

This code just returns myclass and creates Student class. I want to add JSON in student class and use it.

Dynamic class is:

class CType
{
    public class MyClassBuilder
    {
        AssemblyName asemblyName;
        public MyClassBuilder(string ClassName)
        {
            this.asemblyName = new AssemblyName(ClassName);
        }
        public object CreateObject(string[] PropertyNames, Type[] Types)
        {
            if (PropertyNames.Length != Types.Length)
            {
                Console.WriteLine("The number of property names should match their corresopnding types number");
            }

            TypeBuilder DynamicClass = this.CreateClass();
            this.CreateConstructor(DynamicClass);
            for (int ind = 0; ind < PropertyNames.Count(); ind++)
                CreateProperty(DynamicClass, PropertyNames[ind], Types[ind]);
            Type type = DynamicClass.CreateType();

            return Activator.CreateInstance(type);
        }
        private TypeBuilder CreateClass()
        {
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(this.asemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            TypeBuilder typeBuilder = moduleBuilder.DefineType(this.asemblyName.FullName
                                , TypeAttributes.Public |
                                TypeAttributes.Class |
                                TypeAttributes.AutoClass |
                                TypeAttributes.AnsiClass |
                                TypeAttributes.BeforeFieldInit |
                                TypeAttributes.AutoLayout
                                , null);
            return typeBuilder;
        }
        private void CreateConstructor(TypeBuilder typeBuilder)
        {
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
        }
        private void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
        {
            FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

            PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
            ILGenerator getIl = getPropMthdBldr.GetILGenerator();

            getIl.Emit(OpCodes.Ldarg_0);
            getIl.Emit(OpCodes.Ldfld, fieldBuilder);
            getIl.Emit(OpCodes.Ret);

            MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName,
                  MethodAttributes.Public |
                  MethodAttributes.SpecialName |
                  MethodAttributes.HideBySig,
                  null, new[] { propertyType });

            ILGenerator setIl = setPropMthdBldr.GetILGenerator();
            Label modifyProperty = setIl.DefineLabel();
            Label exitSet = setIl.DefineLabel();

            setIl.MarkLabel(modifyProperty);
            setIl.Emit(OpCodes.Ldarg_0);
            setIl.Emit(OpCodes.Ldarg_1);
            setIl.Emit(OpCodes.Stfld, fieldBuilder);

            setIl.Emit(OpCodes.Nop);
            setIl.MarkLabel(exitSet);
            setIl.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
    }
}

标签: c# .net class
1条回答
疯言疯语
2楼-- · 2019-08-25 02:44

This should do the trick

class Program
{
    static void Main(string[] args)
    {

        CType.MyClassBuilder MCB = new CType.MyClassBuilder("Student");

        dynamic obj1 = MCB.CreateObject(new string[3] { "ID", "Name", "Address" }, new Type[3] { typeof(int), typeof(string), typeof(string) });
        Type studentType = obj1.GetType();
        var listOfStudents = CreateList(obj1);


        for (int i = 0; i < 10; i++)
        {
            var newObj = Activator.CreateInstance(obj1.GetType());
            studentType.GetProperty("ID").SetValue(newObj, i);
            newObj.Name = "Name" + i;
            listOfStudents.Add(newObj);
        }

        Console.WriteLine(listOfStudents.GetType().FullName);
        foreach (var student in listOfStudents)
            Console.WriteLine(student.ID + " "+ student.Name);


        Console.ReadLine();
    }

    public static List<T> CreateList<T>(T obj)
    {
        return new List<T>();
    }
}
查看更多
登录 后发表回答