程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 關於Emit中動態類型TypeBuilder創建類標記的一點思考

關於Emit中動態類型TypeBuilder創建類標記的一點思考

編輯:C#入門知識

 

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved