zoukankan      html  css  js  c++  java
  • 动态创建类并添加属性赋值

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

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

    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;
        }

  • 相关阅读:
    自学Linux Shell5.2-shell内建命令history alias
    自学Linux Shell5.1-shell父子关系
    vue2.0 实现导航守卫(路由守卫)
    vue2.0 关于Vue实例的生命周期
    vue2.0 正确理解Vue.nextTick()的用途
    vue2.0 项目build后资源文件报错404的解决方案
    vue2.0 vetur插件提示 'v-for' directives require 'v-bind:key' directives 的解决办法
    vue2.0 微信oauth认证的正确调用位置
    vue2.0 样式表引入的方法 css sass less
    vue2.0 配置sass
  • 原文地址:https://www.cnblogs.com/zhangruisoldier/p/12896232.html
Copyright © 2011-2022 走看看