C# 反射

释放双眼,带上耳机,听听看~!

反射概念:

  1. 在程序运行时动态获取类或对象的信息,具体包括了

动态 获取 加载程序集(Assmebly)

动态 获取 类型信息(如类、接口 等) – Type对象

动态 获取 类型的成员信息(如方法,字段,属性等);

  1. 在运行时,动态创建类型实例(new),以及 调用 和 访问 这些 实例 成员;

.Net反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为.Net的反射机制。

.Net反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;

类型 作用
Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
Module 包含模块的程序集以及模块中的类等。还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
ConstructorInfo 构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用Type的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
MethodInfo 方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用Type的 GetMethods 或 GetMethod 方法来调用特定的方法。
FieldInfo 字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
EventInfo 事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
PropertyInfo 属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
ParameterInfo 参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等

1
1

在程序运行时,动态获取程序集:

C# 反射C# 反射


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
1class Program
2    {
3        static void Main(string[] args)
4        {
5            Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
6            Person p = new Person();
7            p.TestAssembly();
8
9            Console.ReadKey();
10        }
11    }
12
13
14class Person
15    {
16        public string Name { get; set; }
17        public int Age { get; set; }
18        private int Id;
19        public double Sum;
20
21        public void Method1() { }
22        private void Method2() { }
23
24        public void TestAssembly()
25        {
26            Assembly ass = this.GetType().Assembly;
27            Console.WriteLine(ass);
28            Type[] types = ass.GetTypes();
29            foreach (var item in types)
30            {
31                Console.WriteLine(item + "   (types)");
32            }
33            Type currentType = ass.GetType();
34            Console.WriteLine(currentType);
35            Type typeByFullName = ass.GetType("ConsoleApp2.Person");
36            Console.WriteLine(typeByFullName);
37
38            Type type = this.GetType();
39            Console.WriteLine(type);
40            MethodInfo[] methods = this.GetType().GetMethods();
41            foreach (var item in methods)
42            {
43                Console.WriteLine(item + "    (methods)");
44            }
45            var members = this.GetType().GetMembers();
46            foreach (var item in members)
47            {
48                Console.WriteLine(item);
49            }
50            var member = this.GetType().GetMember("Name");
51            foreach (var item in member)
52            {
53                Console.WriteLine(item);
54            }
55            FieldInfo field = type.GetField("Sum");
56            Console.WriteLine(field);
57            PropertyInfo prop = type.GetProperty("Name");
58            Console.WriteLine(prop);
59        }
60    }
61

View Code

C# 反射

在程序运行时,动态创建类型实例:

C# 反射C# 反射


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
1class Program
2    {
3        static void Main(string[] args)
4        {
5            Person p = new Person();
6            p.CreatePersonObject();
7
8            Console.ReadKey();
9        }
10    }
11
12
13
14public void CreatePersonObject()
15        {
16            Type type = this.GetType();
17            Person p = Activator.CreateInstance(type) as Person;
18            Person p1 = Activator.CreateInstance<Person>();
19
20            PropertyInfo prop = type.GetProperty("Name");
21            prop.SetValue(p1, "toto",null);
22            Console.WriteLine(p1.Name);
23
24            MethodInfo method = type.GetMethod("SayHi");
25            method.Invoke(p1, null);
26            MethodInfo method1 = type.GetMethod("ShowNumber");
27            object[] arrParams = { 13 };
28            method1.Invoke(p1, arrParams);
29            MethodInfo method2 = type.GetMethod("GetString");
30            string retStr = method2.Invoke(p1, null).ToString();
31            Console.WriteLine(retStr);
32        }
33
34        public void SayHi()
35        {
36            Console.WriteLine("Hiiiiiiiiiiii");
37        }
38        public void ShowNumber(int no)
39        {
40            Console.WriteLine(no);
41        }
42        public string GetString()
43        {
44            return "Hello";
45        }
46

View Code

C# 反射

通过反射找出类型的构造函数,然后调用构造函数来获取实例引用

C# 反射C# 反射


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1public static void GetConstructor()
2        {
3            Type tpdatetime = Type.GetType("System.DateTime", false);
4            if (tpdatetime != null)
5            {
6                ConstructorInfo constructor = tpdatetime.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });
7                if (constructor != null)
8                {
9                    object instance = constructor.Invoke(new object[] { 2019, 12, 17, 16, 11, 24 });
10                    if (instance != null)
11                    {
12                        PropertyInfo[] props = tpdatetime.GetProperties(BindingFlags.Public | BindingFlags.Instance);
13                        Console.WriteLine("以下是DateTime实例的属性值列表");
14                        foreach (PropertyInfo item in props)
15                        {
16                            object objval = item.GetValue(instance,null);
17                            Console.WriteLine("{0,-15}:{1}",item.Name,objval??string.Empty);
18                        }
19                    }
20                }
21            }
22        }
23

View Code

C# 反射

Activator.CreateInstance和Assembly.CreateInstance。这2种方法创建实例的区别:

Load、LoadFile、LoadForm:


1
2
3
4
1Assembly assembly = Assembly.Load("Ruanmou.DB.Sqlserver");//1 动态加载 默认加载当前路径的dll文件,不需要后缀,该方法传入的是Dll的名字,该Dll必须位于全局缓存GAC中才行,不然会报“System.IO.FileLoadException: 未能加载文件或程序集”的异常。
2Assembly assembly1 = Assembly.LoadFile(@"E:\online7\20160928Advanced7Course2Reflection\MyReflection\MyReflection\bin\Debug\Ruanmou.DB.Sqlserver.dll");// 必须是完整路径
3Assembly assembly2 = Assembly.LoadFrom("Ruanmou.DB.Sqlserver.dll");// 可以是当前路径  也可以是完整路径
4

通过反射调用类的私有成员:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1Person p = new Person();
2Type tPerson = p.GetType();
3//得到私有字段的值:
4FieldInfo privateField = tPerson.GetField("privateFields", BindingFlags.Instance | BindingFlags.NonPublic);
5//设置私有成员的值:
6privateField.SetValue(p, "修改后的私有字段值");
7Console.WriteLine(privateField.GetValue(p));
8
9//得到私有属性的值:
10PropertyInfo privateProp = tPerson.GetProperty("PrivateProperties", BindingFlags.Instance | BindingFlags.NonPublic);
11//设置私有属性的值:
12privateProp.SetValue(p, "修改后的私有属性值",null);
13Console.WriteLine(privateProp.GetValue(p,null));
14
15//调用私有方法
16MethodInfo privateMethod = tPerson.GetMethod("SayHi", BindingFlags.Instance | BindingFlags.NonPublic);
17privateMethod.Invoke(p, null);
18

 

 

 

给TA打赏
共{{data.count}}人
人已打赏
安全技术

Bootstrap框架之排版

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索