04.反射

Type

1.获取Type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Type(类的信息类)
//它是反射功能的基础!
//它是访问元数据的主要方式。
//使用 Type 的成员获取有关类型声明的信息
//有关类型的成员(如构造函数、方法、字段、属性和类的事件)

#region 获取 Type
//1.万物之父 object 中的 GetType() 可以获取对象的 Type
int a = 42;
Type type = a.GetType();
Console.WriteLine(type);

//2.通过 typeof:关键字传入类名也可以得到对象的
Type type2 = typeof(int);
Console.WriteLine(type2);

//3.通过类的名字也可以获取类型
//注意类名必须包含命名空间不然找不到
Type type3 = Type.GetType("System.Int32");
Console.WriteLine(type3);
#endregion

2.获取程序集信息 Assembly

1
2
3
4
5
6
#region 得到类的程序集信息
//可以通过 Type 可以得到类型所在程序集信息
Console.WriteLine(type.Assembly);
Console.WriteLine(type2.Assembly);
Console.WriteLine(type3.Assembly);
#endregion

3.获取类中的所有公共成员 GetMembers

1
2
3
4
5
6
7
8
9
10
#region 获取类中的所有公共成员
//首先得到 Type
Type t = typeof(Test);
//然后得到所有公共成员
//需要引用命名空间 using System.Ref1 ection;
MemberInfo[]infos t.GetMembers();
for(int i=0; i<infos.Length; i++){
Console.WriteLine(infos[i]);
}
#endregion

4.获取构造函数 GetConstructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//1.获取所有构造函数
ConstructorInfo[] ctors = t.GetConstructors();
for(int i=0; i<ctors.Length; i++) {
Console.WriteLine(ctors[i]);
}

//2.获取其中一个构造函数并执行
//得构造函数传入 Type 数组数组中内容按顺序是参数类型
//执行构造函数传入 object 数组表示按顺序传入的参数

//2-1 得到无参构造
ConstructorInfo info = t.GetConstructor(new Type[]);
//执行无参构造无参构造没有参数传 nu11Test obj info.Invoke(null) as Test;
Console.WriteLine(obj.j);

//2-2 得到有参构造
ConstructorInfo info2 = t.Getconstructor(new Type[] {typeof(int)});
obj info2.Invoke(new object[]2 }as Test;
Console.WriteLine(obj.str); I
ConstructorInfo info3 =t.Getconstructor(new Type[]typeof(int), typeof(string)});
obj info3.Invoke(new object[]4,"444444"}) as Test;
Console.WriteLine(obj.str);

5.获取类的公共成员变量 GetFields

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#region 获取类的公共成员变量

//1.得到所有成员变量
FieldInfo[] fieldInfos = t.GetFields();
for(int i=0; i<fieldInfos.Length; i++) {
Console.WriteLine(fieldInfos[i]);
}

//2.得到指定名称的公共成员变量
FieldInfo infoJ = t.GetField("j");
Console.WriteLine(infoJ);

//3.通过反射获取和设置对像的值 Test
test = new Test();
test.j=99;
test.str = "2222";

//3-1 通过反射获取对象的某个变量的值
Console.WriteLine(infoJ.GetValue(test));
//3-2 通过反射设置指定对象的某个变量的值
infoJ.Setvalue(test,100);
Console.WriteLine(infoJ.GetValue(test));

5.获取类的公共成员方法GetMethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#region 获取类的公共成员方法
//通过 Type 类中的 GetMethod 方法得到类中的方法
//MethodInfo 是方法的反射信息
Type strType typeof(string);
MethodInfo[] methods = strType.GetMethods();
for(int i=0; i < methods.Length; i++){
Console.WriteLine(methods[i]);
}

//1.如果存在方法重载用 Type 数组表示参数类型
MethodInfo substr strType.GetMethod("Substring", new Type[]typeof(int), typeof(int)});

//2.调用该方法
//注意:如果是静态方法 Invoke 中的第一个参数传 nul1 即可
string str "Hello, World!";

//第一个参数相当于是哪个对象要执行这个成员方法
object result = substr.Invoke(str, new object[] { 7,5 });
Console.WriteLine(result);

Activator

**1.快速实例化对象Activator

1
2
3
4
5
6
7
8
9
10
#region Activator
//用于快速实例化对象的类
//用于将 Type 对像快捷实例化为对象/先得到 Type
//然后快速实例化一个对像 Type testType=typeof(Test);
//1.无参构造
Test testobj = Activator.CreateInstance(testType) as Test;
Console.WriteLine(testobj.str);
//2.有参数构造
testobj = Activator.CreateInstance(testType,99) as Test;
Console.WriteLine(testobj.j);

Assimbly

**1.程序集类Assimbly

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
#region Assembly 
//程序集类
//主要用来加载其它程序集,加载后
//才能用 Type 来使用其它程序集中的信息/如果想要使用不是自己程序集中的内容需要先加载程序集
//比如 d11 文件(库文件)
//简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类

//三种加载程序集的函数
//一般用来加载在同一文件下的其它程序集
//Assembly asemb.1y2=Assemb1y.Load("程序集名称");

//一般用来加载不在同一文件下的其它程序集
//Assembly asemb1y=Assemb1y.LoadFrom("包含程序集清单的文件的名称或路径");
//Assembly asembly3=Assembly.LoadFile("要加载的文件的完全限定路径");

//1.先加载一个指定程序集
Assembly asembly = Assembly.LoadFrom(@"C:\Users\MECHREVO\Desk");
Type[] types = asembly.GetTypes();
for(int i=0; i<types.Length; i++)
{
Console.WriteLine(types[i]);
}
//2.再加载程序集中的一个类对像之后才能使用反射
Type icon = asembly.GetType("Lesson18_练习题. Icon");
MemberInfo[]members icon.GetMembers();
for(int i=0; i<members.Length; i++)
{
Console.WriteLine(members[i]);
}

//3.通过反射实例化一个 icon 对像
//首先得到枚举 Type 来得到可以传入的参数
Type moveDir=asembly.GetType("Lesson18 练习题. E_MoveDir");
FieldInfo right moveDir.GetField("Right");
//直接实例化对象
object iconobj Activator.CreateInstance(icon,
10,5, right.Getvalue(null));
//得到对象中的方法通过反射
MethodInfo move = icon.GetMethod("Move");
MethodInfo draw = icon.GetMethod("Draw");
MethodInfo clear = icon.GetMethod("Clear");
Console.Clear();
while(true)
{
Thread.sleep(1000);
clear.Invoke(iconobj, null);
move.Invoke(iconobj, null);
draw.Invoke(iconobj, null);
}