2019年 7月12日 自己练习C#的反射

---恢复内容开始---

 

1.反射时候 只有GetMembers默认返回公共成员 就是定义public可以去返回 其他私有的 和保护的则不可以

2.在GetMembers里边写上BindingFlags就是可以获取其他的成员 包括私有的 和 可保护的 中间用|号隔开 BindingFlags.NonPublic 就是指定非公共成员也在搜索中 BindingFlags.Instance 指定实例成员也在搜索中

3.只关注该类成员 BindingFlags.DeclaredOnly 不关注其父类成员 

 static void Main(string[] args)
        {
            Type t = typeof(ReClass);
            Func<MemberTypes, string> getType = (x) => { switch (x) { case MemberTypes.Field: { return "字段"; } case MemberTypes.Method: { return "方法"; } case MemberTypes.Property: { return "属性"; } default: { return "未知"; } } };
            MemberInfo[] minfos = t.GetMembers(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (MemberInfo minfo in minfos)
            {
                Console.WriteLine(minfo.Name+"类型"+getType(minfo.MemberType));
            }
            Console.Read();
        }
        public class ReClass
        {
            private  int _test3;
            private int _test1 { get; set; }
            protected int Test2 { get; set; }
            public int Test3 { get; set; }
            public void show()
            {

            }
            public static void Show2()
            {

            }
            public static void Show3()
            {

            }
        }

 以上代码 就是先定义一个自己的类 然后进行反射 利用Type 进行 第二行 代码 为循环遍历 返回类型 有四个类型 为 方法 属性 字段 未知   第三行为要实现的 因为GetMembers默认返回公共成员 而我们要添加几个 让它全部进行返回 然后就是进行循环遍历 全都显示 出来 前边为名字 后边为属性  获取他们为什么类型对的关键字为GetMembers

Type t = typeof(ReClass);
            MemberInfo[] minfos = t.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (FieldInfo minfo in minfos)
            {
                Console.WriteLine("字段名称:{0} 字段类型:{1}",minfo.Name,minfo.FieldType.ToString());
            }

这里是获取他们的数据类型 具体关键字为GetFields 可以获取他们的数据类型

 

 

Type t = typeof(ReClass);
            ReClass rc = new ReClass();
            rc.Test3 = 3;
            FieldInfo[] finfos = t.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (FieldInfo minfo in finfos)
            {
                Console.WriteLine("字段名称:{0} 字段类型:{1} rc中的值为{2}",minfo.Name,minfo.FieldType.ToString(),minfo.GetValue(rc));
            }
            Console.Read();

 

这段代码为获取他们的值 先实例化那个类 然后为第三个进行赋值 值为3 然后 就是依然的不为公共的获取不出来 那么我们就 添加 类型 然后 遍历循环 输出他们的名称 类型 最后输出 值

 

 Type t = typeof(ReClass);
            ReClass rc = new ReClass();
            rc.Test3 = 3;
            FieldInfo[] finfos = t.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (FieldInfo minfo in finfos)
            {
                minfo.SetValue(rc,100);
                Console.WriteLine("字段名称:{0} 字段类型:{1} rc中的值为{2}",minfo.Name,minfo.FieldType.ToString(),minfo.GetValue(rc));
            }

这里同上 依然是 只不过变化的是 在遍历循环里边 赋值了100 因为是在循环里边进行赋值 所有他们的值都是100

 

 Type t = typeof(ReClass);
            ReClass rc = new ReClass();
            rc.Test3 = 3;
            PropertyInfo[] finfos = t.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (PropertyInfo minfo in finfos)
            {
                MethodInfo getinfo = minfo.GetGetMethod(true);
                Console.WriteLine("get方法名称:{0} 返回值类型:{1} 参数数量{2} MSIL代码长度{3} 局部变量数量{4}", getinfo.Name, getinfo.ReturnType.ToString(), getinfo.GetParameters().Count(), getinfo.GetMethodBody().GetILAsByteArray().Length, getinfo.GetMethodBody().LocalVariables.Count);
                MethodInfo setinfo = minfo.GetSetMethod(true);
                Console.WriteLine("get方法名称:{0} 返回值类型:{1} 参数数量{2} MSIL代码长度{3} 局部变量数量{4}", setinfo.Name, setinfo.ReturnType.ToString(), setinfo.GetParameters().Count(), setinfo.GetMethodBody().GetILAsByteArray().Length, setinfo.GetMethodBody().LocalVariables.Count);
                setinfo.Invoke(rc, new object[] { 123 });
                object obj = getinfo.Invoke(rc, null);
                Console.WriteLine("方法名:{0} 内部值{1}", minfo.Name, obj);

这里循环每个属性 通过GetGetMethod 获取get方法 调用该方法时如果传入true则无法获取不公开的get方法  通过GetSetMethod获取get方法 调用该方法时如果传入true则无法获取不公开的set方法 

接着我们输出了该方法的返回类型参数数量MSIL代码长度以及局部变量的数量  最后调用了set方法将值改变,然后再通过调用get方法获取这个属性的值

 

Type t = typeof(ReClass);
            ReClass rc = new ReClass();
            rc.Test3 = 3;
            MethodInfo[] finfos = t.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (MethodInfo minfo in finfos)
            {
                 if(minfo.GetParameters().Count()>0&&minfo.GetParameters()[0].ParameterType==typeof(string))
                {
                    object obj = minfo.Invoke(rc, new[] { "123" });
                    MethodBody mbody = minfo.GetMethodBody();
                    Console.WriteLine("拥有参数的方法名:{0} 返回值类型:{1} 参数1类型:{2} 参数1名称{3} 方法调用后的返回的值{4}",
                    minfo.Name, minfo.ReturnType.ToString(), minfo.GetParameters()[0].ParameterType.ToString(), minfo.GetParameters()[0].Name, obj.ToString());
                }
                 else
                {
                    MethodBody mbody = minfo.GetMethodBody();
                    Console.WriteLine("没有参数的方法名:{0} 返回值类型:{1}", minfo.Name, minfo.ReturnType.ToString());
                }
            }
 
 
 
public class ReClass
        {
            private  int _test3;
            private int _test1 { get; set; }
            protected int Test2 { get; set; }
            public int Test3 { get; set; }
            public string show(string s)
            {
                string a;
                return s;
            }
            public static void Show2()
            {
            }
            public static string Show3(string s)
            {
                int b;
                int c;
                return s;
            }
        }

 

 

改代码 在方法里边写入参数 然后在上边判断是否有参数 遍历循环输出 是否有参数 返回值类型 然后有参数的再输出 第一个参数类型 第一个参数名称 方法调用后的返回值

 

---恢复内容结束---

2019年 7月12日 自己练习C#的反射

上一篇:前端笔记之JavaScript面向对象(一)Object&函数上下文&构造函数&原型链


下一篇:MVC(Model(模型) View(视图) Controller(控制器))