zoukankan      html  css  js  c++  java
  • 基础命名空间:反射 using System.Reflection

    反射概念:
           .Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,程序集包含模块 模块包含类型,类型又包含
    成员,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息, .NET Framework提供命名空间System.Refection和
    System.Type,可以获取已加载的程序集和程序集中定义的类型(类、接口、值类型)的信息也可以使用反射在运行时创建类型实例,将类型绑定到现有
    对象,或主从现有对象中获取类型,调用和访问这些实例

    练习示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Business;
    
    namespace FirstReflection
    {
        public class ComputerFactory : IMessageHandler
        {
            //品牌
            public string brand { get; set; }
            //地址
            public string address { get; set; }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            public ComputerFactory()
            { }
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="brand"></param>
            public ComputerFactory(string brand,string address)
            {
                this.brand = brand;
                this.address = address;
            }
    
            public void displayBrand()
            {
                Console.WriteLine(this.brand);
            }
    
            public void displayaddress(string address)
            {
                Console.WriteLine("public:生产地址:{0}",address);
            }
    
            public static void displayaddress()
            {
                Console.WriteLine("public static共有方法:生产地址:本部");
            }
    
            private void privatedisplayaddress(string address)
            {
                Console.WriteLine("private私有方法:生产地址:{0}", address);
            }
        }
    }
    

      通过Assembly类的load()方法加载程序集,并在程序集中查找定义的类型......

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Reflection;
    
    namespace FirstReflection
    {
       /*反射:
        1.获取方法的信息
        2.调用方法
        3.构造对象
        4.从程序集中加载类型
        */
    
    
    
        public class Program
        {
            //查看程序集中所有的类
            public static void ShowClassName(Type[] types)
            {
                Console.WriteLine("查看程序集中所有的类:");
                foreach (Type type in types)
                {
                    Console.WriteLine(type);
                }
            }
            
            public static void ShowModuleName(Module[] modules)
            {
                Console.WriteLine("查看程序集中所有的模块:");
                foreach (Module module in modules)
                {
                    Console.WriteLine(module);
                }
            }
    
            public static void ShowPropertyName(PropertyInfo[] properties)
            {
                Console.WriteLine("查看该类型的属性:");
                foreach (PropertyInfo property in properties)
                {
                    Console.WriteLine(property);
                }
            }
    
            static void Main(string[] args)
            {
    
                //[0]
                //加载程序集
                Assembly assembly = Assembly.Load("FirstReflection");
                //Assembly assembly = Assembly.LoadFrom("FirstReflection.exe");
                
                //[1]:查看程序集中所有的类
                Type[] types = assembly.GetTypes();
                ShowClassName(types);
    
                //[2]:查看模块
                Module[] modules = assembly.GetModules();
                ShowModuleName(modules);
    
                //[3]:取得类类型
                Type getType = assembly.GetType("FirstReflection.ComputerFactory");
                Type getTypeTwo = Type.GetType("FirstReflection.ComputerFactory");
                //Console.WriteLine(getType);//输出:FirstReflection.ComputerFactory
    
                //[4]:查看该类的属性
                PropertyInfo[] properties = getType.GetProperties();
                ShowPropertyName(properties);//protected、private 属性未获取到
    
                //[5]:查看实现的接口
                Type[] iTypes = getType.GetInterfaces();
                Console.WriteLine("查看继承的接口:");
                foreach (var item in iTypes)
                {
                    Console.WriteLine(item.Name);
                }
    
                //[6]:查看类的所有方法(只获取public方法) *****
                /*【get;set访问器也会被解析】*/
                MethodInfo[] methods = getType.GetMethods();
                Console.WriteLine("查看类的所有方法:");
                foreach (var item in methods)
                {
                    Console.WriteLine(item);
                }
    
                //[6-2]:查找public方法 与getType.GetMethods()返回结果一样
                MethodInfo[] publicMethods = getType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
                Console.WriteLine("查看类的public方法:");
                foreach (var item in publicMethods)
                {
                    Console.WriteLine(item);
                }
    
                //[6-1]:查找私有方法(protected、private)
                //NonPublic指反射,但找到的属性/特性是NonPublic访问的
                //Instance 只是找到实例的引用对象,类似c++中的实例句柄指针(当然这个是枚举类型)
                MethodInfo[] nonPublicMethods = getType.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);
                Console.WriteLine("查看类的私有方法:");
                foreach (var item in nonPublicMethods)
                {
                    Console.WriteLine(item);
                }
    
                //[7]:获取构造函数
                ConstructorInfo[] constructors = getType.GetConstructors();
                Console.WriteLine("查看类的够着方法:");
                foreach (var item in constructors)
                {
                    Console.WriteLine(item);
                }
    
                //[8]:创建实例
                //方法1(有问题)
                object IBMcomputer = Assembly.GetAssembly(getType).CreateInstance("ComputerFactory");
                //方法2        
                object[] constructParam = new object[] { "HP","北京" };
                //带参数
                object HPcomputer = Activator.CreateInstance(getType, constructParam);
                //不带参数
                object HPcomputer2 = Activator.CreateInstance(getType, null);
    
                //[9]:使用反射调用方法(public方法)
                foreach (MethodInfo m in publicMethods)
                {
                    if (m.Name == "displayaddress")
                    {//调用public void displayaddress(string address)()
                        object[] Param = new object[] { "北京" };
                        m.Invoke(HPcomputer2, Param);
                    }
                }
                //[9-1]:使用反射调用方法 (NonPublic 方法)
                MethodInfo met = getType.GetMethod("privatedisplayaddress", BindingFlags.Instance | BindingFlags.NonPublic);
                object[] Param2 = new object[] { "北京" };
                met.Invoke(HPcomputer2, Param2);
    
                //[9-*]其他
    
                Console.ReadLine();
    
            }
        }
            
    }

    查看结果:

      

    其中:查看类的所有方法出现 get_brand(), set_brand() 说明 get/set访问器在编译时 生成的公有方法get_brand(), set_brand()

     步骤:

    1.加载程序集 使用Assembly类的Load()或者LoadFrom()方法加载程序集,区别是后者需要加入程序集的后缀名,例如.DLL .exe

    2.找到相应的命名空间+类 Type类型也是抽象类,只能通过GetType()或者typeof()来实现

    3.获取类的方法 getMethod() 根据需要调用的方法的访问级别 public protected privat 及static传入相应的参数 方法名+ (BindingFlags.Instance | BindingFlags.Public)等

    4.调用方法 MethodInfo.Invoke() 传入实例,方法的参数

  • 相关阅读:
    分模块开发创建service子模块——(八)
    分模块开发创建dao子模块——(七)
    分模块开发创建父工程——(六)
    Html设置html与body元素高度问题
    原生JS给元素添加class属性
    【雪花点】雪花点的显示——(二)
    【雪花点】雪花点的显示——(一)
    Dom4j用Xpath获取节点——(六)
    Dom4j向XML中指定位置添加、删除、修改节点——(五)
    [置顶] 详细解读:技术有没有前途之分
  • 原文地址:https://www.cnblogs.com/ashleyboy/p/3670657.html
Copyright © 2011-2022 走看看