基础命名空间:反射 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() 传入实例,方法的参数

posted @ 2014-04-17 14:22  互联网荒漠  阅读(2648)  评论(0编辑  收藏  举报