码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-07-05 19:08:54      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   os   for   

 

利用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()));
                    }
                }
            }

关于Emit中动态类型TypeBuilder创建类标记的一点思考,布布扣,bubuko.com

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

标签:style   blog   color   使用   os   for   

原文地址:http://www.cnblogs.com/xiaodlll/p/3822618.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!