• 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;
                }
            }

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

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

  • 相关阅读:
    14 微服务电商【黑马乐优商城】:day02-springcloud(理论篇一:HttpClient的简单使用)
    14 微服务电商【黑马乐优商城】:day01-springboot(Thymeleaf快速入门)
    14 微服务电商【黑马乐优商城】:day01-springboot(理论篇)
    1.1 行列式:二阶三阶n阶行列式
    ubuntu:make工程管理器大致了解
    ubuntu:VIM使用
    机器学习:朴素贝叶斯邮件分类(python实现)
    ubuntu 添加快速启动
    ubuntu:软件包
    Ubuntu:远程管理ubuntu文件系统
  • 原文地址:https://www.cnblogs.com/hanzhuopeng/p/11178252.html
Copyright © 2020-2023  润新知