zoukankan      html  css  js  c++  java
  • c#之反射(Reflection)

    一、反射是什么

    1. 反射就是.Net FrameWork框架为我们提供的一个帮助类库,它可以读取我们通过编译后生成的dll和exe文件里面metadate的信息。
    2. 反射可以动态的加载dll和exe文件,动态的创建对象,动态的调用方法,动态的获取属性的值和为属性赋值等等......

    二、通过反射获取信息

    在C#程序中,我们可以用 System.Reflection 命名空间下的 Assembly 类来加载dll文件,从而来获取里面的信息,代码如下:

                        Assembly assembly = Assembly.Load("MyReflection.DB.SqlService");
                        foreach (var item in assembly.GetModules())
                        {
                            Console.WriteLine("Module完全限定名:" + item.FullyQualifiedName);
                        }
                        foreach (var type in assembly.GetTypes())//遍历该dll下的所有类型
                        {
                            Console.WriteLine("Type完全限定名:" + type.FullName);
                            foreach (var item in type.GetConstructors())//遍历类型下的所有构造函数
                            {
                                Console.WriteLine(item.Name);
                            }
                            foreach (var item in type.GetMethods())//遍历类型下的所有公开方法
                            {
                                Console.WriteLine(item.Name);
                            }
                            foreach (var item in type.GetProperties())//遍历类型下的所有公开属性
                            {
                                Console.WriteLine(item.Name);
                            }
                            foreach (var item in type.GetFields())//遍历类型下的所有公开字段
                            {
                                Console.WriteLine(item.Name);
                            }
                        }

    三、创建对象

    上面我们可以获取到dll中的信息,接下来我们就来使用一些信息来创建对象,来调用对象里的方法。

                            Assembly assembly = Assembly.Load("MyReflection.DB.SqlService");//1.动态加载dll
                            Type typeHelper = assembly.GetType("MyReflection.DB.SqlService.SqlServerHelper");//2.获取类型信息
                            object objDbHelper = Activator.CreateInstance(typeHelper);//3.创建对象
                            IDBHelper dbHelper = (IDBHelper)objDbHelper;
                            dbHelper.Query();

    四、调用方法

    通过上面我们知道要想调用方法,就必须先知道类型,然后强转成相应的类型才能调用方法,接下来我们就来实现不需要知道类型就来调用一系列方法:

    首先上面创建对象的三个步骤是少不了的。

         Assembly assembly = Assembly.Load("MyReflection.DB.SqlService");//1.动态加载dll
            Type typeHelper = assembly.GetType("MyReflection.DB.SqlService.ReflectionTest");//2.获取类型信息
            object objDbHelper = Activator.CreateInstance(typeHelper);//3.创建对象

    1、调用无参数的方法:

            public void show1() 
            {
                Console.WriteLine("这里是{0}的show1", this.GetType());
            }
    
            MethodInfo show1 = typeHelper.GetMethod("show1");
            show1.Invoke(objDbHelper, null);

    结果如下:

    2、调用有参数的方法:

            public void show2(int id)
            {
                Console.WriteLine("这里是{0}的show2", this.GetType());
            }
            MethodInfo show2 = typeHelper.GetMethod("show2");
            show2.Invoke(objDbHelper, new object[] { 11 });

    结果如下:

    3、调用有参数并且重载的方法:

         public void show3()
            {
                Console.WriteLine("这里是{0}无参的show3", this.GetType());
            }
            public void show3(string name,int id)
            {
                Console.WriteLine("这里是{0}带string参数和int参数的show3", this.GetType());
            }
            public void show3(int id,string name)
            {
                Console.WriteLine("这里是{0}带int参数和string参数的show3", this.GetType());
            }
            public void show3(int id)
            {
                Console.WriteLine("这里是{0}带int参数的show3", this.GetType());
            }
            public void show3(string name)
            {
                Console.WriteLine("这里是{0}带string参数的show3", this.GetType());
            }
    
    
            MethodInfo show3_1 = typeHelper.GetMethod("show3", new Type[] { typeof(string) });
            show3_1.Invoke(objDbHelper, new object[] { "dafs" });
    
            MethodInfo show3_2 = typeHelper.GetMethod("show3", new Type[] { typeof(int) });
            show3_2.Invoke(objDbHelper, new object[] { 111 });
    
            MethodInfo show3_3 = typeHelper.GetMethod("show3", new Type[] { typeof(int), typeof(string) });
            show3_3.Invoke(objDbHelper, new object[] { 111, "dfafsd" });

    结果如下:

    4、调用有私有的方法:

            private void show4(string name)
            {
                Console.WriteLine("这里是{0}的show4", this.GetType());
            }
            MethodInfo show4 = typeHelper.GetMethod("show4", BindingFlags.Instance |//访问私有方法
                BindingFlags.Public | BindingFlags.NonPublic);
            show4.Invoke(objDbHelper, new object[] { "dfafsd" });

    结果如下:

    4、调用静态的方法:静态方法在调用的时候要不要对象都行,推荐不要放对象,原因就不说了,都懂的

            public static void show5(string name)
            {
                Console.WriteLine("这里是{0}的show5", typeof(ReflectionTest));
            }
            MethodInfo show5 = typeHelper.GetMethod("show5");//静态方法
            show5.Invoke(null, new object[] { "dfafsd" });//不放对象
            show5.Invoke(objDbHelper, new object[] { "dfafsd" });//放对象

    结果如下:

     

    五、为属性赋值和设置值

    接直来我们创建一个 People 类

        public class People
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

    然后实例化:

                        People people = new People
                        {
                            Id = 1001,
                            Name = "张三"
                        };

    接下来我们来获取属性值和设置属性值:

                        Type type = typeof(People);
                        object oPeople = Activator.CreateInstance(type);
                        foreach (var item in type.GetProperties())//字段设置和获取的语法和属性一样
                        {
                            Console.WriteLine("{0}={1}", item.Name, item.GetValue(oPeople));
                            if (item.Name.Equals("Id"))
                            {
                                item.SetValue(oPeople, 1002);
                            }
                            if (item.Name.Equals("Name"))
                            {
                                item.SetValue(oPeople, "李四");
                            }
                        }

    结果如下:

  • 相关阅读:
    str_replace函数的使用规则和案例详解
    phpqrcode.php 生成二维码图片用于推广
    常用的正则表达式验证
    Java:原生javaWeb下载pdf文件
    设计模式:七大原则
    Spring Boot:整合Hikari+Oracle+p6spy
    Spring Boot:开启全局事务
    Java8:按照对象的属性,对List集合分组
    SpringMVC统一异常处理
    JSR303校验的基本使用和结合AOP使用
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/8794486.html
Copyright © 2011-2022 走看看