C#反射使用方法过程及步骤,供大家参考,具体内容如下
1. 定义要访问类的全名
2. 获取该类的类型
3. 实例化该类
4. 获取该类的字段、属性,方法
5. 设置该字段或属性内容,或调用其方法
从而达到使用字符串访问相应类的目的。
示例:
1. 根据窗口类的名称,产生一个新的窗口,相当于new 窗口类
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//1. 定义窗口类名称:(窗口类的字符串名字,需要全路径名,否则获取不到TYPE) string customClassName = @"IBAutoDeal.IBDealForms." + hasPanel.Text; //2. 获取字符串customClassName(某个窗口类的字符串名字)指定类的Type Type customClassType = Type.GetType(customClassName); //3. 生成指定Type的实例,相当于new 类 object customClassObj = Activator.CreateInstance(customClassType); // 4. 对新生成的类进行操作, 本例把new 出的窗口赋值给一个窗口变量 panelForm = customClassObj as Form; // 由此达到使用类的字符串名生成一个该类的实例供后续程序的使用 |
2. 根据类的字符串名字,给该类的字段或属性赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//反射功能使用及步骤:以下示例为给字符串类名生成一个实例,并给该类的属性或字段赋值 // 1. 定义类名称:(类的字符串名字,需要全路径名,否则获取不到TYPE) string customVaribleName = @"IBAutoDeal.IBDealClass.CommVar" ; // 2. 获取字符串 customVaribleName指定类的Type Type customVaribleType = Type.GetType(customVaribleName); // 3. 生成指定Type的实例,相当于new 类 object customAaribleObj = Activator.CreateInstance(customVaribleType); // 4. 获取该类字段,本例是给一个公共的窗体变量赋值,而该变量在此是字段 // 如果是给该类的属性赋值,就需要使用 PropertyInfo pi = customVaribleType.GetField("v" + hasPanel.Text) // 在该类中,某个域是属性还是字段呢?我个人的判断是,若该域提供了GET,SET方法,就为属性,否则为字段,也不知道正确否? FieldInfo pi = customVaribleType.GetField( "v" + hasPanel.Text); // 5. 给该字段赋值,该字段是个窗口类变量,customClassObj就是示例1中根据字符串产生的窗口类 pi.SetValue(customAaribleObj, customClassObj); // 通过以上5个步骤,完成了根据字符串的名字,给相应类的字段赋值 |
3. 根据类的字符串名字,读取字段值,并使用该字段值(示例中,该字段值是窗体,该示例是销毁该窗体)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 1. 定义类名称:(类的字符串名字,需要全路径名,否则获取不到TYPE) string customVaribleName = @"IBAutoDeal.IBDealClass.CommVar" ; // 2. 获取字符串 customVaribleName指定类的Type Type customVaribleType = Type.GetType(customVaribleName); // 3. 生成指定Type的实例,相当于new 类 object customAaribleObj = Activator.CreateInstance(customVaribleType); // 4. 获取该类字段,本例是给一个公共的窗体变量赋值,而该变量在此是字段 // 如果是给该类的属性赋值,就需要使用 PropertyInfo pi = customVaribleType.GetField("v" + hasPanel.Text) // 在该类中,某个域是属性还是字段呢?我个人的判断是,若该域提供了GET,SET方法,就为属性,否则为字段,也不知道正确否? FieldInfo pi = customVaribleType.GetField( "v" + e.Panel.Name); // 5. 读取该字段的值(本示例该字段值为窗体,读取窗体变量,把销毁该窗体) (pi.GetValue(customAaribleObj) as Form).Dispose(); // 6. 再为该字段赋空值 pi.SetValue(customAaribleObj, null ); |
4. 示例3原来是通过switch来判断需要关闭那个窗口,这样就会有很多的case语句,通过反射,就用示例3的6行代码取代了,下面贴出原程序的代码,目的是让大家了解反射的作用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
// 被示例3取代的原代码段(根据e.Panel.Name的值对相应窗口关闭,并给公用变量赋值) switch (e.Panel.Name) { case "FrmAccountStatistics" : CommVar.vFrmAccountStatistics.Dispose(); CommVar.vFrmAccountStatistics = null ; break ; case "frmPositionManager" : CommVar.vfrmPositionManager.Dispose(); CommVar.vfrmPositionManager = null ; break ; case "frmTrader" : CommVar.vfrmTrader.Dispose(); CommVar.vfrmTrader = null ; break ; case "frmLog" : CommVar.vfrmLog.Dispose(); CommVar.vfrmLog = null ; break ; case "frmDataTransPlant" : CommVar.vfrmDataTransPlate.Dispose(); CommVar.vfrmDataTransPlate = null ; break ; case "frmAccountTJ" : CommVar.vfrmAccountTJ.Dispose(); CommVar.vfrmAccountTJ = null ; break ; case "frmGridViewConfig" : CommVar.vfrmGridViewConfig.Dispose(); CommVar.vfrmGridViewConfig = null ; break ; case "frmTaticlistExcel" : CommVar.vfrmTaticlistExcel.Dispose(); CommVar.vfrmTaticlistExcel = null ; break ; case "frmQuoteLst" : CommVar.vfrmQuoteLst.Dispose(); CommVar.vfrmQuoteLst = null ; break ; case "frmProduct" : CommVar.vfrmProduct.Dispose(); CommVar.vfrmProduct = null ; break ; default : break ; } |
5. 针对 T 的泛类型定义的类,给属性赋值示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public static T ReadClass<T>( string pClassName) where T: class { //1. 定义类名称:(因为有传入的T类,所以不需要类的名称了) //2.获取类T的TYPE,注意,前面例子中是通过字符串取类型,使用的是Type.GetType() Type classType = typeof (T); //3. 生成指定 T 的实例,前面例子中,我们使用的是Activator.CreateInstance(classType) T ClassObj = Activator.CreateInstance<T>(); //4. 定义类的属性变量,因程序要多次读取不同的属性,在此定义一个局部变量 PropertyInfo classPropertyInfo = null ; string tableName = "TradeParameters" ; //DataTable必须转成DataView才能使用RowFilter DataTable vDt = DataTableHelper.ReadTable(tableName); DataView vDv = vDt.DefaultView; vDv.RowFilter = $ "ClassName = '{pClassName}'" ; if (vDv.Count > 0) { string pName, pVaule; foreach (DataRow dr in vDv) { pName = dr[ "AttributeName" ].ToString(); pVaule = dr[ "AttributeValue" ].ToString(); //5. 获取指定名称属性 classPropertyInfo = classType.GetProperty(pName); if (classPropertyInfo != null ) { //6. 给指定属性赋值 classPropertyInfo.SetValue(ClassObj, pVaule); } } } return ClassObj; } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://laoshifu.blog.csdn.net/article/details/120468957