步步为营-31-反射基础

Posted 逍遥小天狼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了步步为营-31-反射基础相关的知识,希望对你有一定的参考价值。

说明 :简单练习反射的基础包括获取dll中的数据,方法等

程序集之间互相调用可以通过:a添加引用,b引入命名空间,来实现.但是只能调用public修辞的方法和属性.另外还可通过程序集调用

1 创建一个控制台应用程序

2 创建一个类库,用于生成dll,注意修改属性,使其生成的路径为控制台应用程序bin/debug目录(方便修改)

3 获取程序集数据

 加载程序集,获取程序集数据

 3.1 加载程序集--Assembly.LoadFile(path);

  
 public static  Assembly  LoadAssembly() 
        {
            //01 注意是绝对路径
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll");
            //02 加载程序集
            return Assembly.LoadFile(path);
        }
加载程序集

 3.2 获取数据

  3.2.1 方法A获得程序集所有数据类型 ass.GetTypes()

  3.2.2 方法B获得程序集所有--public数据类型 ass.GetExportedTypes()

  3.2.3 方法C根据数据名称获得指定数据,可以是私有的 ass.GetType("Common.Teacher")

  
#region 02-获取数据(abc三种常见的方法)

        /// <summary>
        /// 方法A获得程序集所有数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] A_GetTypes(Assembly ass)
        {
            Type[] types = ass.GetTypes();
            return types;
        }
        /// <summary>
        /// 方法B获得程序集所有--public数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] B_GetExportedTypes(Assembly ass)
        {
            Type[] types = ass.GetExportedTypes();
            return types;
        }
        /// <summary>
        /// 方法C根据数据名称获得指定数据,可以是私有的
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>

        private static Type[]  C_GetType(Assembly ass)
        {
            Type  atype = ass.GetType("Common.Teacher");
            Type[] types = { atype };
            return types;
        }
        #endregion
获取数据


小结代码+运行效果

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace 反射_基础
{
    class Program
    {
        static void Main(string[] args)
        {
           Assembly ass = LoadAssembly();
           if (ass!=null)
           {
               Console.WriteLine("获得所有数据");
              Type[] typesA =  A_GetTypes(ass);
              ShowItem(typesA);
              Console.WriteLine();

              Console.WriteLine("获得所有public数据");
              Type[] typesB = B_GetExportedTypes(ass);
              ShowItem(typesB);
              Console.WriteLine();

              Console.WriteLine("获得指定数据,可以是私有的");
              Type[] typeC = C_GetType(ass);
              ShowItem(typeC);
           }
            Console.Read();
        }

       

        #region 01加载程序集
        public static  Assembly  LoadAssembly() 
        {
            //01 注意是绝对路径
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll");
            //02 加载程序集
            return Assembly.LoadFile(path);
        }
        #endregion

        #region 02-获取数据(abc三种常见的方法)

        /// <summary>
        /// 方法A获得程序集所有数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] A_GetTypes(Assembly ass)
        {
            Type[] types = ass.GetTypes();
            return types;
        }
        /// <summary>
        /// 方法B获得程序集所有--public数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] B_GetExportedTypes(Assembly ass)
        {
            Type[] types = ass.GetExportedTypes();
            return types;
        }
        /// <summary>
        /// 方法C根据数据名称获得指定数据,可以是私有的
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>

        private static Type[]  C_GetType(Assembly ass)
        {
            Type  atype = ass.GetType("Common.Teacher");
            Type[] types = { atype };
            return types;
        }
        #endregion

        #region 03-显示数据
        private static void ShowItem(Type[] types) 
        {
            foreach (var item in types)
            {
                Console.WriteLine(item.Name);
            }
        }
        #endregion
    }
}
View Code

4 创建对象

        4.1 CreateInstance,注意是通过无参构造函数创建的.
        4.2 Activator.CreateInstance创建对象

  
 #region 04创建对象(两种方法)
        /// <summary>
        /// 创建对象方法A,CreateInstance,注意是通过无参构造函数创建的.
        /// 方法B ,Activator.CreateInstance创建对象
        /// </summary>
        /// <param name="ass"></param>
        /// <returns></returns>
         private static object A_CreateInstance(Assembly ass)
        {
            //object obj = ass.CreateInstance("Common.Student");//如果不含有 无参构造函数,会报错
            object obj = ass.CreateInstance("Common.Teacher");
            return obj;
        }

        /// <summary>
         /// 方法B ,Activator.CreateInstance创建对象
        /// </summary>
        /// <param name="ass"></param>
        /// <returns></returns>
         private static object B_CreateInstance(Assembly ass)
         {
             
             //1获取创建对象的类型
            Type type  = ass.GetType("Common.Student");
             object obj = Activator.CreateInstance(type,"张三",22);
             return obj;
         }
        #endregion
CreateInstance

5 获取创建对象的属性,方法等
  5.1.1GetMethods

  5.1.2GetMethod

  5.2.1GetProperties

  5.2.2GetProperty

  
 #region 05获得创建对象的方法和属性
         public static MethodInfo[] A_GetMethods(object obj) 
         {
             MethodInfo[] mes = obj.GetType().GetMethods();
             return mes;
         }

         public static MethodInfo[] B_GetMethod(object obj,string methodName)
         {
             MethodInfo me = obj.GetType().GetMethod(methodName);
             MethodInfo[] mes ={me};
             return mes;
         }

         public static  PropertyInfo[] A_GetProperties(object obj)
         {
             PropertyInfo [] prs = obj.GetType().GetProperties();
             return prs;
         }

         public static PropertyInfo[] B_GetProperty(object obj, string proName)
         {
             PropertyInfo pr = obj.GetType().GetProperty(proName);
             PropertyInfo[] prs = { pr };
             return prs;
         }

        #endregion
05获得创建对象的方法和属性

   5.3 调用创建对象的SayHello方法
               me[0].Invoke(objB, null);

   5.4 获得Age属性的值
              pro[0].SetValue(objB,55);               
              Console.WriteLine(pro[0].GetValue(objB));

代码小结:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace 反射_基础
{
    class Program
    {
        static void Main(string[] args)
        {
           Assembly ass = LoadAssembly();
           if (ass!=null)
           {
               Console.WriteLine("获得所有数据");
              Type[] typesA =  A_GetTypes(ass);
              ShowItem(typesA);
              Console.WriteLine();

              Console.WriteLine("获得所有public数据");
              Type[] typesB = B_GetExportedTypes(ass);
              ShowItem(typesB);
              Console.WriteLine();

              Console.WriteLine("获得指定数据,可以是私有的");
              Type[] typeC = C_GetType(ass);
              ShowItem(typeC);

               //创建对象
              Console.WriteLine();
              Console.WriteLine("方法A创建对象(必须含有无参构造函数)");
              object objA = A_CreateInstance(ass);
              Console.WriteLine(objA.GetType().Name);
              Console.WriteLine();

              Console.WriteLine("方法B创建对象");
              object objB = B_CreateInstance(ass);
              Console.WriteLine(objB.GetType().Name);
              Console.WriteLine();

               //获得创建对象那个的方法和属性
               Console.WriteLine("创建对象的方法 们");
               MethodInfo[] mes= A_GetMethods(objB);
               ShowMethods(mes);
               Console.WriteLine();

               Console.WriteLine("创建对象的方法 ");              
               MethodInfo[] me = B_GetMethod(objB,"SayHello");
               ShowMethods(me);
               Console.WriteLine();

               Console.WriteLine("创建对象的属性 们");
               PropertyInfo[] pros = A_GetProperties(objB);
               ShowProperties(pros);
               Console.WriteLine();

               Console.WriteLine("创建对象的属性");
               PropertyInfo[] pro = B_GetProperty(objB,"Age");
               ShowProperties(pro);
               Console.WriteLine();

               //调用方法的值
               Console.WriteLine("调用创建对象的SayHello方法");
               me[0].Invoke(objB, null);
               Console.WriteLine();

               //获得Age属性的值
               Console.WriteLine("获得Age属性的值");
               pro[0].SetValue(objB,55);               
               Console.WriteLine(pro[0].GetValue(objB));
               
           }
            Console.Read();
        }

       

        #region 01加载程序集
        public static  Assembly  LoadAssembly() 
        {
            //01 注意是绝对路径
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll");
            //02 加载程序集
            return Assembly.LoadFile(path);
        }
        #endregion

        #region 02-获取数据(abc三种常见的方法)

        /// <summary>
        /// 方法A获得程序集所有数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] A_GetTypes(Assembly ass)
        {
            Type[] types = ass.GetTypes();
            return types;
        }
        /// <summary>
        /// 方法B获得程序集所有--public数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] B_GetExportedTypes(Assembly ass)
        {
            Type[] types = ass.GetExportedTypes();
            return types;
        }
        /// <summary>
        /// 方法C根据数据名称获得指定数据,可以是私有的
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>

        private static Type[]  C_GetType(Assembly ass)
        {
            Type  atype = ass.GetType("Common.Teacher");
            Type[] types = { atype };
            return types;
        }
        #endregion

        #region 03-显示数据
        private static void ShowItem(Type[] types) 
        {
            foreach (var item in types)
            {
                Console.WriteLine(item.Name);
            }
        }
        #endregion

        #region 04创建对象(两种方法)
        /// <summary>
        /// 创建对象方法A,CreateInstance,注意是通过无参构造函数创建的.
        /// 方法B ,Activator.CreateInstance创建对象
        /// </summary>
        /// <param name="ass"></param>
        /// <returns></returns>
         private static object A_CreateInstance(Assembly ass)
        {
            //object obj = ass.CreateInstance("Common.Student");//如果不含有 无参构造函数,会报错
            object obj = ass.CreateInstance("Common.Teacher");
            return obj;
        }

        /// <summary>
         /// 方法B ,Activator.CreateInstance创建对象
        /// </summary>
        /// <param name="ass"></param>
        /// <returns></returns>
         private static object B_CreateInstance(Assembly ass)
         {
             
             //1获取创建对象的类型
            Type type  = ass.GetType("Common.Student");
             object obj = Activator.CreateInstance(type,"张三",22);
             return obj;
         }
        #endregion

        #region 05获得创建对象的方法和属性
         public static MethodInfo[] A_GetMethods(object obj) 
         {
             MethodInfo[] mes = obj.GetType().GetMethods();
             return mes;
         }

         public static MethodInfo[] B_GetMethod(object obj,string methodName)
         {
             MethodInfo me = obj.GetType().GetMethod(methodName);
             MethodInfo[] mes ={me};
             return mes;
         }

         public static  PropertyInfo[] A_GetProperties(object obj)
         {
             PropertyInfo [] prs = obj.GetType().GetProperties();
             return prs;
         }

         public static PropertyInfo[] B_GetProperty(object obj, string proName)
         {
             PropertyInfo pr = obj.GetType().GetProperty(proName);
             PropertyInfo[] prs = { pr };
             return prs;
         }

        #endregion

        #region 06获得属性方法
         public static void ShowMethods(MethodInfo[] mes) 
         {
             foreach (MethodInfo item in mes)
             {
                 Console.WriteLine(item.Name);
             }
         }

         public static void ShowProperties(PropertyInfo[] pros)
         {
             foreach (PropertyInfo item in pros)
             {
                 Console.WriteLine(item.Name);
             }
         }
        #endregion
    }
}
View Code

仔细观察获得的方法值有SayHello公共的,没有SayHi私有的方法.而且GetMethod也无法调用私有的方法

6 反射中常用的方法  

 if (ass!=null)
           {
             
                Type[] types = A_GetTypes(ass);
               //此时数组中依次存在 Brid,Person,Student,Teacher四个元素

                //Studnet能否 里氏转换 为Person  子类赋值给父类
                bool a = types[1].IsAssignableFrom(types[2]);//true
                Console.WriteLine(a);
                //Student是否是Person的实例
                Type type = ass.GetType("Common.Student");
                object obj = Activator.CreateInstance(type, "张三", 22);
                bool b = types[1].IsInstanceOfType(obj);//true    
          
                bool d = types[0].IsInstanceOfType(obj);//false              
                Console.WriteLine(b);
                Console.WriteLine(d);

                //Teacher是否是Person的子类---没有接口
                bool c = types[3].IsSubclassOf(types[1]);//true
                Console.WriteLine(c);

               //Person是否是抽象函数
                bool e = types[1].IsAbstract;
                Console.WriteLine(e);
           }
常用方法

运行效果

总体代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace 反射_基础
{
    class Program
    {
        static void Main(string[] args)
        {
           Assembly ass = LoadAssembly();
           #region 获取程序集的数据
           if (ass == null)
           {
               Console.WriteLine("获得所有数据");
               Type[] typesA = A_GetTypes(ass);
               ShowItem(typesA);
               Console.WriteLine();

               Console.WriteLine("获得所有public数据");
               Type[] typesB = B_GetExportedTypes(ass);
               ShowItem(typesB);
               Console.WriteLine();

               Console.WriteLine("获得指定数据,可以是私有的");
               Type[] typeC = C_GetType(ass);
               ShowItem(typeC);

               //创建对象
               Console.WriteLine();
               Console.WriteLine("方法A创建对象(必须含有无参构造函数)");
               object objA = A_CreateInstance(ass);
               Console.WriteLine(objA.GetType().Name);
               Console.WriteLine();

               Console.WriteLine("方法B创建对象");
               object objB = B_CreateInstance(ass);
               Console.WriteLine(objB.GetType().Name);
               Console.WriteLine();

               //获得创建对象那个的方法和属性
               Console.WriteLine("创建对象的方法 们");
               MethodInfo[] mes = A_GetMethods(objB);
               ShowMethods(mes);
               Console.WriteLine();

               Console.WriteLine("创建对象的方法 ");
               MethodInfo[] me = B_GetMethod(objB, "SayHello");
               ShowMethods(me);
               Console.WriteLine();

               Console.WriteLine("创建对象的属性 们");
               PropertyInfo[] pros = A_GetProperties(objB);
               ShowProperties(pros);
               Console.WriteLine();

               Console.WriteLine("创建对象的属性");
               PropertyInfo[] pro = B_GetProperty(objB, "Age");
               ShowProperties(pro);
               Console.WriteLine();

               //调用方法的值
               Console.WriteLine("调用创建对象的SayHello方法");
               me[0].Invoke(objB, null);
               Console.WriteLine();

               //获得Age属性的值
               Console.WriteLine("获得Age属性的值");
               pro[0].SetValue(objB, 55);
               Console.WriteLine(pro[0].GetValue(objB));

           } 
           #endregion

            //bool
           if (ass!=null)
           {
             
                Type[] types = A_GetTypes(ass);
               //此时数组中依次存在 Brid,Person,Student,Teacher四个元素

                //Studnet能否 里氏转换 为Person  子类赋值给父类
                bool a = types[1].IsAssignableFrom(types[2]);//true
                Console.WriteLine(a);
                //Student是否是Person的实例
                Type type = ass.GetType("Common.Student");
                object obj = Activator.CreateInstance(type, "张三", 22);
                bool b = types[1].IsInstanceOfType(obj);//true    
          
                bool d = types[0].IsInstanceOfType(obj);//false              
                Console.WriteLine(b);
                Console.WriteLine(d);

                //Teacher是否是Person的子类---没有接口
                bool c = types[3].IsSubclassOf(types[1]);//true
                Console.WriteLine(c);

               //Person是否是抽象函数
                bool e = types[1].IsAbstract;
                Console.WriteLine(e);
           }
         
            Console.Read();
        }

       

        #region 01加载程序集
        public static  Assembly  LoadAssembly() 
        {
            //01 注意是绝对路径
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll");
            //02 加载程序集
            return Assembly.LoadFile(path);
        }
        #endregion

        #region 02-获取数据(abc三种常见的方法)

        /// <summary>
        /// 方法A获得程序集所有数据类型
        /// </summary>
        /// <param name="ass">程序集名称</param>
        /// <returns></returns>
        private static Type[] A_GetTypes(Assembly ass)
        {
            Type[] types = ass.GetTypes();
            一步步学Metal图形引擎6-《漫反射》

java 反射代码片段

一步步学OpenGL 31 -《PN(Point-Normal)三角形曲面细分》

步步UP2️⃣——反射的获取字节码Class对象和Class对象功能概述

步步UP1️⃣——反射概述

一步步学Metal图形引擎7-《镜面反射》