1. 程式人生 > >C#反射 字符串轉為實體類,並做為參數傳入泛型方法中使用

C#反射 字符串轉為實體類,並做為參數傳入泛型方法中使用

subst type xxd main.c 發現 get director col asm

工作中有這樣一個需求,有N張不同的報表,每張報表對應一個數據源,以前采用SQL統計方式 ,統計數據采用內存方式,首先在內在裏定義了數據源對應實體。統計條件用lamdba表達式式實現,通過工具對單元格進行定義。在實現過程中針對每一張表來寫取數顯示是很Low的了,取數條件定義都是規則的,統計實現就是一段C#代碼,但是要針對不同的數據源也就是不同的List<Entity>,通過研究發現通過泛型和反射可以實現。

根據字符串獲取實體類型

 1 private Type getEntity(string typeName)
 2 {
 3     var workPath = AppDomain.CurrentDomain.BaseDirectory;
4 string[] files = Directory.GetFiles(workPath, "XXX.Utils.dll", SearchOption.TopDirectoryOnly); 5 foreach (string file in files) 6 { 7 string ext = file.Substring(file.LastIndexOf(".")); 8 if (ext != ".dll") continue; 9 try 10 { 11 Assembly asm = Assembly.LoadFile(file);
12 Type[] allTypes = asm.GetTypes(); 13 foreach (Type t in allTypes) 14 { 15 if (t.IsSubclassOf(typeof(XXDataRecord))) 16 { 17 if (t.Name.ToUpper().IsSame(typeName.ToUpper())) 18 return t;
19 } 20 } 21 } 22 catch 23 { 24 return null; 25 } 26 } 27 return null; 28 }

泛型方法定義

1 public XXDataMemory BuildDataMemoryPattern<T>(XXParams zb, string id) where T : XXDataRecord, new()

調用方法代碼

 1 var obj = new GenerateDataHelper(_Param);
 2 Type myGenericClassType = obj.GetType();
 3 //MakeGenericMethod 設置泛型參數類型
 4 MethodInfo mi = myGenericClassType.GetMethod("BuildDataMemoryPattern").MakeGenericMethod(typeEntity);
 5 int count = 0;
 6 //設置調用方法參數
 7 object[] invokeArgs = new object[] { zb, id, count };
 8 //調用
 9 var dt = (DataTable)mi.Invoke(obj, invokeArgs);
10 //獲取回返數據
11 recordCount = (int)invokeArgs[9];

下面是全部代碼,具體功能實現略過

技術分享圖片
 1 public class UtilFetchHelper 
 2 {
 3     //獲取實體類型
 4     private Type getEntity(string typeName)
 5     {
 6         var workPath = AppDomain.CurrentDomain.BaseDirectory;
 7         string[] files = Directory.GetFiles(workPath, "XXX.Utils.dll", SearchOption.TopDirectoryOnly);
 8         foreach (string file in files)
 9         {
10             string ext = file.Substring(file.LastIndexOf("."));
11             if (ext != ".dll") continue;
12             try
13             {
14                 Assembly asm = Assembly.LoadFile(file);
15                 Type[] allTypes = asm.GetTypes();
16                 foreach (Type t in allTypes)
17                 {
18                     if (t.IsSubclassOf(typeof(XXDataRecord)))
19                     {
20                         if (t.Name.ToUpper().IsSame(typeName.ToUpper()))
21                             return t;
22                     }
23                 }
24             }
25             catch
26             {
27                 return null;
28             }
29         }
30         return null;
31     }
32 
33     public DataTable BuildDataMemoryPattern(XXParams zb, string id, out int recordCount)
34     {
35         //根據傳入參數獲取實體名稱
36         var entityName = GetDataSourceEntityName(zb);
37         //獲取實體類型
38         Type typeEntity = getEntity(entityName);
39         if (typeEntity == null)
40             return  null;
41         var obj = new GenerateDataHelper(_Param);
42         Type myGenericClassType = obj.GetType();
43         MethodInfo mi = myGenericClassType.GetMethod("BuildDataMemoryPattern").MakeGenericMethod(typeEntity);
44         int count = 0;
45         object[] invokeArgs = new object[] { zb, id, count };
46         var dt = (DataTable)mi.Invoke(obj, invokeArgs);
47         //這裏獲取回返數據
48         recordCount = (int)invokeArgs[9];
49         return dt;
50     }
51 }
52 
53 public class GenerateDataHelper
54 {
55     private List<XXDataRecord> _DataList;
56     private List<XXDataRecord> DataList
57     {
58         set { _DataList = value; }
59         get { return _DataList; }
60     }    
61     
62     private List<T> GetDataSource<T>() where T : XXDataRecord, new()
63     {
64         var _DataList = new List<T>();
65         var dt = DB.ExecuteDataTable("Select * From XX");
66         for (int i = 0; i < dt.Rows.Count; i++)
67         {
68             var dataEnt = new T();
69             for (int j = 0; j < dt.Columns.Count; j++)
70             {
71                 dataEnt[dt.Columns[j].ColumnName] = dt.Rows[i][j];
72             }
73             _DataList.Add(dataEnt);
74         }
75         return _DataList;        
76      }
77         
78         
79     public XXDataMemory BuildDataMemoryPattern<T>(XXParams zb, string id) where T : XXDataRecord, new()
80     {
81         List<T> DataList = new List<T>();
82         DataList = GetDataSource<T>();
83         //以下是具體實現代碼 針對DataList查詢操作
84     }
85 }
View Code

C#反射 字符串轉為實體類,並做為參數傳入泛型方法中使用