C#--反射使用Start!-获取对象的字段/属性/方法/成员/构造方法

前言:https://blog.csdn.net/qq_32452623/article/details/53192398
学编程一年多,现在才真正开始用反射,有点晚了,但是用好反射真的很重要,算是很方便,这么久了不会用反射,其实是有一小点点的low的,所以准备好好学习一下,写博客记录一下,权当笔记和动力了.\*^_^*/
What-反射是什么?
反射,Reflection,就是通过一个类对象,可以获取他所在类的其他全部成员和属性,包括私有的.
Why-为什么要使用发射?
##1.获取该成员的其他属性信息来使用

例如我想写个导出表格,但是列名想定义在对应的实体类model中,好一一对应,代码侵入性小,容易维护,于是自定义了一个注解,放在这个model需要导出的变量上,我需要将这个model的对象作为方法传入,然后拿出这个类所有对象成员变量上定义的这个自定义属性.
##2.配合泛型,写出通用的一个工具类,一般用于框架性的代码

例如:接着上个例子,我现在有两个表格要导出,部门表和员工表,所以有两个类,部门model,员工model.这个时候,可以使用泛型类型传参,然后通过反射获取传过来的类型的自定义注解信息
##3.例如反射获取一个类的私有方法或者属性

例如:需要用到一个类里面的方法,但是这个方法是不对外暴露的,怎么办?我们不怕,因为我们有反射.
#How-使用反射Start

首先我们定义这么一个类,分别定义的public,protected,private修饰的字段,属性,方法.,下面我们用反射获取试一下.

namespace ConsoleApplication1
{   
   public enum GenderEnum
    {
        Boy = 0,
        Girl = 1,
        Dog = 2
    }
    
    public class WorkerModel
    {

        /// <summary>
        /// 字段
        /// </summary>
        public string _name = "Hathway";
        private int _id = 32;
        protected bool _isAdmin = true;
        public GenderEnum _gender = GenderEnum.Girl;


        /// <summary>
        /// 属性
        /// </summary>
        public string Name { get; set; }
        public GenderEnum Gender { get; set; }
        private int Id { get; set; }
        protected bool isAdmin { get; set; }

        /// <summary>
        /// 方法
        /// </summary>
        public void Android()
        { 
        }
        protected void iOS()
        { 
        }
        private void WindowPhone()
        { 
        }


        /// <summary>
        /// 构造方法
        /// </summary>
        public WorkerModel()
        { 
        }

        public WorkerModel(string name, int id, GenderEnum gender, bool isAdmin) 
        { 
        }


    }

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
定义这个类对象,我们去使用反射获取一下这个对象的各类信息

   WorkerModel worker = new WorkerModel() { 
            Name = "Jay",
            Gender = GenderEnum.Boy,
            };
1
2
3
4
1.字段信息—FieldInfo----type.getGetFields()
        public static  void GetFieldValue(Object obj)
        {
            //得到对象的类型
            Type type = obj.GetType();
            //得到字段的值,只能得到public类型的字典的值
            FieldInfo[]  fieldInfos = type.GetFields();
            foreach (var f in fieldInfos)
            {
                //字段名称
                string fieldName = f.Name;
                //字段类型
                string fieldType = f.FieldType.ToString();
                //字段的值
                string fieldValue = f.GetValue(obj).ToString();
                
                Console.WriteLine("fieldName------>" + fieldName );
                Console.WriteLine( "fieldType------>" + fieldType );
                Console.WriteLine("fieldValue------>" + fieldValue);

                Console.WriteLine("-------------------------------------------------------------------");

            }
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


2.属性信息—PropertyInfo----type.GetProperties()
        public static void GetPropertyInfo(Object obj)
        {
            Type type = obj.GetType();
            PropertyInfo[] propertyInfo = type.GetProperties();
           
            foreach (var p in propertyInfo)
            {
                            
                string propertyName = p.Name
                string propertyValue = p.GetValue(obj,null).ToString();
                Console.WriteLine("propertyName------>" + propertyName);
                Console.WriteLine("propertyValue----->" + propertyValue);
                Console.WriteLine("-------------------------------------------------------------------");

            }
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


3.方法信息—MethodInfo----type.GetMethods()
        public static void GetMethodInfo(Object obj)
        {
            Type type = obj.GetType();
            //获取所有public修饰的方法
            MethodInfo[] methodInfo = type.GetMethods();
            
            foreach (var m in methodInfo)
            {
                string methodName = m.Name;
              
                Console.WriteLine("methodName------>" + methodName);
             
                Console.WriteLine("-------------------------------------------------------------------");
            }
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


4.成员信息—MemberInfo----type.GetMembers()
        public static void GetMemberInfo(Object obj)
        {
            Type type = obj.GetType();
            MemberInfo[] memberInfo = type.GetMembers();

            foreach (var m in memberInfo)
            {
                string memberName = m.Name;
 
                Console.WriteLine("memberName------>" + memberName);
              
                Console.WriteLine("-------------------------------------------------------------------");
            }
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14


5.构造方法信息—ConstructorInfo----type.GetConstructors()
    private static void GetConstructorInfo(Object obj)
        {
            Type type = obj.GetType();
            //获取所有public修饰的构造方法
            ConstructorInfo[]  constructorInfo = type.GetConstructors();
            foreach (var c in constructorInfo)
            {
                string constructorName = c.Name;
                ParameterInfo[] constructorParams = c.GetParameters();
                Console.WriteLine("constructorName------>" + constructorName);
                foreach (var p in constructorParams)
                {
                    Console.WriteLine("Params------ p.Name-->" + p.Name);
                    Console.WriteLine("Params------ p.Type--->"+ p.ParameterType);
                }
                Console.WriteLine("-------------------------------------------------------------------");

            }
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


public怎么够? 获取受保护的成员信息
现在获取私有属性的请问激动不激动,按耐住,完全出乎你的意料,只需要改动一句代码就好了, 以GetFields为例:
1.获取public修饰

 //得到字段的值,只能得到public类型的字典的值
 FieldInfo[]  fieldInfos = type.GetFields();
1
2
2.获取private 和protected的值

//获取全部类型的值
 FieldInfo[] fieldInfos = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

1
2
3
看我们使用第二个方法得到的字段信息是怎样的呢,打印出来看看:


哈哈,很明显,我们获取了所有的字段,连属性默认创建的隐藏字段都打印出来了,看来获取的方式是正确的.剩下的Method,Member等就不贴图了,说实话,这个图黑底白字看着好刺眼,贴的还心塞,大家下去可以打印看看,会发现很多你想不到的方法哟~~
好了,回归主题,注意观察,我们用的是同一个方法名,只是传递的是参数不同,是不同的方法重写而已,如下:
        //
        // 摘要: 
        //     返回当前 System.Type 的所有公共字段。
        //
        // 返回结果: 
        //     表示为当前 System.Type 定义的所有公共字段的 System.Reflection.FieldInfo 对象数组。 - 或 - 如果没有为当前
        //     System.Type 定义的公共字段,则为 System.Reflection.FieldInfo 类型的空数组。
        public FieldInfo[] GetFields();
        //
        // 摘要: 
        //     当在派生类中重写时,使用指定绑定约束,搜索为当前 System.Type 定义的字段。
        //
        // 参数: 
        //   bindingAttr:
        //     一个位屏蔽,由一个或多个指定搜索执行方式的 System.Reflection.BindingFlags 组成。 - 或 - 零,以返回 null。
        //
        // 返回结果: 
        //     表示为当前 System.Type 定义的匹配指定绑定约束的所有字段的 System.Reflection.FieldInfo 对象数组。 - 或
        //     - 如果没有为当前 System.Type 定义的字段,或者如果没有一个定义的字段匹配绑定约束,则为 System.Reflection.FieldInfo
        //     类型的空数组。
        public abstract FieldInfo[] GetFields(BindingFlags bindingAttr);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
最后
很晚了,回去睡觉了,这周有时间,会专门抽时间看一下关于BindFlags的具体使用.因为我试的时候发现必须要加上BindFlags.Instance参数,否则就获取不到,强迫症一定要知道是为什么,找到答案后会写篇博客的. 晚安,csdn,晚安,大家,晚安,自己^_^
想知道BindFlags.Instance为什么一定要使用的小伙伴们点这里.


————————————————
版权声明:本文为CSDN博主「DRPrincess」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_32452623/article/details/53192398

猜你喜欢

转载自blog.csdn.net/u014090257/article/details/119725876
今日推荐