关于Emit中动态类型TypeBuilder创建类标记的一点思考_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 关于Emit中动态类型TypeBuilder创建类标记的一点思考

关于Emit中动态类型TypeBuilder创建类标记的一点思考

 2014/7/3 17:49:04  xiaodl  程序员俱乐部  我要评论(0)
  • 摘要: 利用TypeBuilder是可以动态创建一个类型,现在有个需求,动态生成一个dll,创建类型EmployeeEx,需要继承原dll里面的Employee类,并包含Employee类上的所有类标记。 网上有很多例子,//创建TypeBuilder。TypeBuildermyTypeBuilder=myModBuilder.DefineType(typeName,TypeAttributes.Public);myTypeBuilder.SetParent(type)
  • 标签:动态类型 创建 创建类

 

利用TypeBuilder是可以动态创建一个类型,现在有个需求,动态生成一个dll,创建类型EmployeeEx,需要继承原dll里面的Employee类,并包含Employee类上的所有类标记。

 

网上有很多例子

//创建TypeBuilder。   
            TypeBuilder myTypeBuilder = myModBuilder.DefineType(typeName, 
                                                            TypeAttributes.Public);

            myTypeBuilder.SetParent(type);

 

大概处理方式如下:

CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { }); 
      myTypeBuilder.SetCustomAttribute(customAttributeBuilder);



att = type.GetCustomAttributes(typeof(DefaultPropertyAttribute), false); 
            if (att != null && att.Length > 0) { 
                DefaultPropertyAttribute dea = att[0] as DefaultPropertyAttribute; 
                customAttributeBuilder = new CustomAttributeBuilder(typeof(DefaultPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { dea.Name }); 
                myTypeBuilder.SetCustomAttribute(customAttributeBuilder); 
             }

 

但是,这些都是已知类标记是Serializable或者DefaultProperty,如果原dll中的Employee再加个自定义标记,我们还需要再改程序,如何能够动态继承到类标记,TypeBuilder.SetCustomAttribute提供了2个重载SetCustomAttribute(CustomAttributeBuilder customBuilder)和SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)。这两个都是需要ConstructorInfo来构造类标记。而我们通过类型Employee得到的类标记是通过反射得到的object[] atts = type.GetCustomAttributes(false);这是object数组,不能直接给ConstructorInfo使用。

 

所以就有了下面的代码,来动态产生标记。

#region 标记
            object[] atts = type.GetCustomAttributes(false);
            if (atts != null && atts.Length > 0) {
                foreach (Attribute item in atts) {
                    if (item == null) continue;
                    try {
                        CustomAttributeBuilder c = null;
                        ConstructorInfo[] conInfos = item.GetType().GetConstructors();
                        ConstructorInfo cons = conInfos[conInfos.Length - 1];
                        ParameterInfo[] args = cons.GetParameters();
                        List<Type> argsList = new List<Type>();
                        List<object> argsValue = new List<object>();
                        if (args.Length > 0) {
                            foreach (var arg in args) {
                                argsList.Add(arg.ParameterType);
                                PropertyInfo pi = item.GetType().GetProperty(arg.Name.Substring(0, 1).ToUpper() + arg.Name.Substring(1));//微软规则首字母小写
                                if (pi != null) {
                                    argsValue.Add(pi.GetValue(item, null));
                                } else {
                                    pi = item.GetType().GetProperty(arg.Name.Remove(0, 1));//我们的规则p+Name
                                    if (pi != null) {
                                        argsValue.Add(pi.GetValue(item, null));
                                    } else {
                                        argsValue.Add(null);
                                    }
                                }
                            }
                        }
                        PropertyInfo[] pis = item.GetType().GetProperties();
                        if (pis.Length > 0) {
                            List<PropertyInfo> piList = new List<PropertyInfo>();
                            List<object> valueList = new List<object>();
                            object[] pValues = new object[pis.Length];
                            for (int i = 0; i < pis.Length; i++) {
                                if (pis[i].CanWrite) {
                                    pValues[i] = pis[i].GetValue(item, null);
                                    if (pValues[i] != null) {
                                        piList.Add(pis[i]);
                                        valueList.Add(pValues[i]);
                                    }
                                }
                            }
                            if (piList.Count > 0) {
                                c = new CustomAttributeBuilder(cons, argsValue.ToArray(), piList.ToArray(), valueList.ToArray());
                            } else {
                                c = new CustomAttributeBuilder(cons, argsValue.ToArray());
                            }
                        } else {
                            c = new CustomAttributeBuilder(cons, argsValue.ToArray());
                        }
                        myTypeBuilder.SetCustomAttribute(c);
                    } catch (Exception ex) {
                        throw new Exception(string.Format("{0}的标记[{1}]重写异常:{2}", typeName, item.ToString(),ex.ToString()));
                    }
                }
            }
发表评论
用户名: 匿名