0%

CSharp Type 类型反射调用

引子

Type 关键字

CSharp 中所有的类型都是 Type

获取 Type 的方法有三种

  1. 使用 typeof 运算符
1
Type t = typeof(int);
  1. 使用 getType() 方法
1
2
int i;
Type t = i.GetType();
  1. 使用Type类的静态方法 GetType()
1
Type t =Type.GetType("System.Double");

Type的属性

属性名 属性含义 扩展
Name 类型名 MyTestType
FullName 类型的完全限定名,包括命名空间 ConsoleApp1.MyTestType
Namespace 类型的命名空间 ConsoleApp1
BaseType 直接父类类型 ConsoleApp1.MyTestParent
UnderlyingSystemType 映射类型 ConsoleApp1.MyTestType

Type的主要方法

方法名 方法含义 入口参数 返回值 扩展
GetFields 获取所有公共字段。 - FieldInfo[] public int Size;
GetField 此方法用于搜索具有指定名称的公共字段。 string FieldInfo -
GetProperties 获取所有公共属性 (get/set) - PropertyInfo[] public int Pos { get; set; }
GetPropertie 此方法用于搜索具有指定名称的公共属性 (get/set) string PropertyInfo -
GetMethods 获取所有公共方法[包含(get/set)] - MethodInfo[] 包含Get/Set方法 如 get_Pos/set_Pos
GetMethod 此方法用于搜索具有指定名称的公共方法[包含get/set] string MethodInfo -
GetMembers 获取所有公共成员 - MemberInfo[] 包含Field / Propertie / Method
GetMember 此方法用于搜索具有指定名称的公共成员 string MemberInfo -

Type 反射调用

1. FiledInfo

使用 GetValue/SetValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void Test()
{
Type myTestType = typeof(MyTestType);
Object myTestInstance = new MyTestType();

FieldInfo fieldInfo1 = myTestType.GetField("Size");

object f1 = fieldInfo1.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Size:" + f1);

fieldInfo1.SetValue(myTestInstance, 10);

object f2 = fieldInfo1.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Size:" + f2);
}

2. PropertyInfo

使用 GetValue/SetValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void Test()
{
Type myTestType = typeof(MyTestType);
Object myTestInstance = new MyTestType();

PropertyInfo propertyInfo = myTestType.GetProperty("Pos");

object p1 = propertyInfo.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Pos:"+ p1);

propertyInfo.SetValue(myTestInstance, 10);

object p2 = propertyInfo.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Pos:" + p2);
}

PropertyInfoSetValue 实际调用的是 set_XXX 方法
PropertyInfoGetValue 实际调用的是 get_XXX 方法

在一个类中如果定义了一个属性 XXX(PosParent) , 就不能再定义 get_XXX(get_PosParent)/set_XXX(set_PosParent)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  class MyTestParent
{
public int SizeParent;
private int posParent;
public int PosParent { get => posParent; set => posParent = value; }

public int mRotationParent;

public int get_PosParent()
{
return posParent;
}
public void set_PosParent(int v)
{
posParent = v;
}
}

编译器会报错

3. MethodInfo

使用 Invoke

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void Test()
{
Type myTestType = typeof(MyTestType);
Object myTestInstance = new MyTestType();

MethodInfo getRotaionMethod = myTestType.GetMethod("GetRotation");
MethodInfo setRotationMethod = myTestType.GetMethod("SetRotation");

object getRotationRet1 = getRotaionMethod.Invoke(myTestInstance,new object[0]);
Console.WriteLine("myTestInstance.MethodInfo GetRotation:" + getRotationRet1);

setRotationMethod.Invoke(myTestInstance, new object[1]{10});

object getRotationRet2 = getRotaionMethod.Invoke(myTestInstance, new object[0]);
Console.WriteLine("myTestInstance.MethodInfo GetRotation:" + getRotationRet2);
}

4. MethodInfo Get/Set

使用 Invoke

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void Test()
{
Type myTestType = typeof(MyTestType);
Object myTestInstance = new MyTestType();

MethodInfo getPosParentMethod = myTestType.GetMethod("get_PosParent");
MethodInfo setPosParentMethod = myTestType.GetMethod("set_PosParent");

object getPosParentRet1 = getPosParentMethod.Invoke(myTestInstance, new object[0]);
Console.WriteLine("myTestInstance.MethodInfo PosParent:" + getPosParentRet1);

setPosParentMethod.Invoke(myTestInstance, new object[1] { 10 });

object getPosParentRet2 = getPosParentMethod.Invoke(myTestInstance, new object[0]);
Console.WriteLine("myTestInstance.MethodInfo PosParent:" + getPosParentRet2);
}

例子代码

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
using System;
using System.Reflection;
using System.Text;

namespace ConsoleApp1
{
public class MyTestParent
{
public int SizeParent;//FieldInfo 父类子类都可以获取,只要是public
private int posParent;//FieldInfo private 无法获取
public int PosParent { get => posParent; set => posParent = value; }// PropertyInfo get_PosParent,set_PosParent

public int mRotationParent;//FieldInfo 父类子类都可以获取,只要是public

//public int get_PosParent()
//{
// return posParent;
//}
//public void set_PosParent(int v)
//{
// posParent = v;
//}

public virtual void SetRotationParent(int r)// memberInfo SetRotationParent
{
mRotationParent = r;
}
public virtual int GetRotationParent()// memberInfo GetRotationParent
{
return mRotationParent;
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("\nSizeParent:");
stringBuilder.Append(SizeParent);
stringBuilder.Append("\nPosParent:");
stringBuilder.Append(PosParent);
stringBuilder.Append("\nRotationParent");
stringBuilder.Append(mRotationParent);

return stringBuilder.ToString();
}
}

public class MyTestType:MyTestParent
{
#region 使用字段访问
public int Size;//FieldInfo public 可以获取
#endregion

#region 使用系统提供的Get/Set 设置访问属性
public int Pos { get; set; }// PropertyInfo get_Pos,set_Pos
#endregion

#region 使用自定义方法 设置属性
private int mRotation;//FieldInfo private 获取不到

public void SetRotation(int r) // memberInfo SetRotation
{
mRotation = r;
}
public int GetRotation() // memberInfo GetRotation
{
return mRotation;
}
#endregion

public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("base.ToString:");
stringBuilder.Append(base.ToString());
stringBuilder.Append("\nSize:");
stringBuilder.Append(Size);
stringBuilder.Append("\nPos:");
stringBuilder.Append(Pos);
stringBuilder.Append("\nRotation");
stringBuilder.Append(mRotation);

return stringBuilder.ToString();
}
}
public class TypeTest
{
public static void Test()
{
//Type类型
Type myTestType = typeof(MyTestType);

//一个不明类型的实例
Object myTestInstance = new MyTestType();

//如何使用这个实例访问 对象属性

Console.WriteLine("myTestType.Name:" + myTestType.Name);
Console.WriteLine("myTestType.FullName:" + myTestType.FullName);
Console.WriteLine("myTestType.Namespace:" + myTestType.Namespace);
Console.WriteLine("myTestType.BaseType:" + myTestType.BaseType);
Console.WriteLine("myTestType.UnderlyingSystemType:" + myTestType.UnderlyingSystemType);

Console.WriteLine("=========fieldInfos=========");
FieldInfo[] fieldInfos = myTestType.GetFields();
for (int i = 0,length = fieldInfos.Length; i < length; i++)
{
FieldInfo fieldInfo = fieldInfos[i];
Console.WriteLine(fieldInfo);
}
Console.WriteLine("==================");

Console.WriteLine("=======FieldInfo Test===========");
FieldInfo fieldInfo1 = myTestType.GetField("Size");
object f1 = fieldInfo1.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Size:" + f1);
fieldInfo1.SetValue(myTestInstance, 10);
object f2 = fieldInfo1.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Size:" + f2);
Console.WriteLine("==================");


Console.WriteLine("=========memberInfos=========");
MemberInfo[] memberInfos = myTestType.GetMembers();
for (int i = 0, length = memberInfos.Length; i < length; i++)
{
MemberInfo fieldInfo = memberInfos[i];
Console.WriteLine(fieldInfo);
}
Console.WriteLine("==================");

Console.WriteLine("=========propertyInfos=========");
PropertyInfo[] propertyInfos = myTestType.GetProperties();
for (int i = 0, length = propertyInfos.Length; i < length; i++)
{
PropertyInfo fieldInfo = propertyInfos[i];
Console.WriteLine(fieldInfo);
}

Console.WriteLine("==================");

Console.WriteLine("=======PropertyInfo Invoke===========");
PropertyInfo propertyInfo = myTestType.GetProperty("Pos");

object p1 = propertyInfo.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Pos:"+ p1);
propertyInfo.SetValue(myTestInstance, 10);
object p2 = propertyInfo.GetValue(myTestInstance);
Console.WriteLine("myTestInstance.Pos:" + p2);
Console.WriteLine("==================");

Console.WriteLine("=========methodInfos=========");
MethodInfo[] methodInfos = myTestType.GetMethods();
for (int i = 0, length = methodInfos.Length; i < length; i++)
{
MethodInfo fieldInfo = methodInfos[i];
Console.WriteLine(fieldInfo);
}
Console.WriteLine("==================");

Console.WriteLine("=======MethodInfo Invoke===========");
MethodInfo getRotaionMethod = myTestType.GetMethod("GetRotation");
MethodInfo setRotationMethod = myTestType.GetMethod("SetRotation");

object getRotationRet1 = getRotaionMethod.Invoke(myTestInstance,new object[0]);
Console.WriteLine("myTestInstance.MethodInfo GetRotation:" + getRotationRet1);

setRotationMethod.Invoke(myTestInstance, new object[1]{10});

object getRotationRet2 = getRotaionMethod.Invoke(myTestInstance, new object[0]);
Console.WriteLine("myTestInstance.MethodInfo GetRotation:" + getRotationRet2);


Console.WriteLine("==================");

Console.WriteLine("=======MethodInfo Get/Set Invoke===========");
MethodInfo getPosParentMethod = myTestType.GetMethod("get_PosParent");
MethodInfo setPosParentMethod = myTestType.GetMethod("set_PosParent");

object getPosParentRet1 = getPosParentMethod.Invoke(myTestInstance, new object[0]);
Console.WriteLine("myTestInstance.MethodInfo PosParent:" + getPosParentRet1);

setPosParentMethod.Invoke(myTestInstance, new object[1] { 10 });

object getPosParentRet2 = getPosParentMethod.Invoke(myTestInstance, new object[0]);
Console.WriteLine("myTestInstance.MethodInfo PosParent:" + getPosParentRet2);

Console.WriteLine("==================");

Console.WriteLine("myTestInstance:" + myTestInstance);


}
}
}

执行结果

欢迎关注我的其它发布渠道