动态创建类并添加属性赋值

碰巧项目使用动态创建类这个稀奇的需求,就研究一下。

有点缺陷就是对属性赋值问题。

public static class MyTypeBuilder
    {
        public static void CreateNewObject()
        {
            var fields = new List<Field>() {
                new Field("EmployeeID", typeof(int)),
                new Field("EmployeeName", typeof(string)),
                new Field("Designation", typeof(string)),
                new Field("Age", typeof(int))  };
            var myType = CompileResultType("MyDynamicType", fields);
            var myObject = Activator.CreateInstance(myType);

           PropertyInfo[] fieldss = myObject.GetType().GetProperties();//获取指定对象的所有公共属性
                        foreach (PropertyInfo pro in fieldss)
                        {
                            foreach (var fie in fields)
                            {
                                if (fie.FieldName == pro.Name)
                                {
                                    pro.SetValue(myObject, fie.FieldValue, null);//给对象赋值
                                }
                            }
                        }
        }
        public static Type CompileResultType(string typeSignature, List<Field> fields)
        {
            TypeBuilder tb = GetTypeBuilder(typeSignature);
            ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public |
            MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type)
            foreach (var field in fields)
                CreateProperty(tb, field.FieldName, field.FieldType);

            Type objectType = tb.CreateType();
            return objectType;
        }
       创建实体
        private static TypeBuilder GetTypeBuilder(string typeSignature)
        {
            //var typeSignature = "MyDynamicType";
            var an = new AssemblyName(typeSignature);
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
                    TypeAttributes.Public |
                    TypeAttributes.Class |
                    TypeAttributes.AutoClass |
                    TypeAttributes.AnsiClass |
                    TypeAttributes.BeforeFieldInit |
                    TypeAttributes.AutoLayout,
                    null);
            return tb;
        }
        实体添加属性
        private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
        {
            FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

            PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr = tb.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 =
                tb.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);
        }
    }

    public class Field
    {
        public Field(string name, Type type)
        {
            this.FieldName = name;
            this.FieldType = type;
        }
        public Field(string name, Type type, string value)
        {
            this.FieldName = name;
            this.FieldType = type;
            this.FieldValue = value;
        }
        public string FieldName;

        public Type FieldType;

        public string FieldValue;
    }

posted on 2020-05-15 17:38  zrSoldier  阅读(451)  评论(0编辑  收藏  举报