当前位置: 代码迷 >> C# >> 浅析C#种的反照
  详细解决方案

浅析C#种的反照

热度:211   发布时间:2016-05-05 05:12:41.0
浅析C#种的反射

 

 1.前言

   以前也写过几篇关于反射的博客(简单反射机制),但都理解的不是很深刻,现在在做项目中又一次的用到了反射,在此再总结一下,对于反射的理解。


 2.什么是反射?

   最近看博客,才理解了反射无处不在,我们经常用到的VS中的智能提示,就是通过反射获取到类的属性,方法等。反射就是动态获取程序集中的元数据来操作类型的。说的通俗一点,反射就是直接调用Bin文件夹下的.dll来创建对象,调用成员,摆脱了以前通过实例化也就是New操作的方法来调用对象的方法。


   小结:反射就是直接调用.dll来创建对象,反射让创建对象的方式发生了变化。


 3.什么是程序集(Assembly)

   程序集是.net中的概念,比如.net中的.exe或者.dll文件都是程序集。可以把其看做是一堆相关的类的打包。比如包含一些资源文件、类型元数据等

      其中调用Assembly(程序集)的GetTypes()方法可以得到程序集中定义的所有的类型

   调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息



 3.Type类介绍

   Type类是实现反射的一个重要的类,通过它可以获取类中所有的信息包括方法、属性等,通过它可以设置属性或者调用方法。

   

 4.重要的类

   Assembly:表示一个程序集,它是一个可重用、可自我描述的公共语言运行时应用程序构造块。            

   Type:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。 

   MethodInfo:发现方法的属性并提供对方法元数据的访问。 

   PropertyInfo:发现属性 (Property) 的属性 (Attribute) 并提供对属性 (Property) 元数据的访问。       


  看了上图,就明白了反射其实就是另外一种机制,另外一种直接通过.dll文件来动态的创建类的对象。                             


   

 5.Demo

   以下是关于这方面知识,自己联系的Demo

<span style="font-size:18px;">using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{    class Program    {        static void Main(string[] args)        {            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ClassLibrary1.dll");            //动态加载一个程序集            //C:\Users\ZHOU\Desktop\lianxi\ConsoleApplication2\bin\Debug            Assembly ass = Assembly.LoadFile("C:/Users/ZHOU/Desktop/lianxi/ConsoleApplication2/bin/Debug/ClassLibrary1.dll");            //获取程序集中公共的类型,通常指的是public的类            Type[] types = ass.GetExportedTypes();            foreach (Type type in types)            {                //类的名字                Console.WriteLine(type.Name);                //类的全名称(命名空间.类名)                Console.WriteLine(type.FullName);            }            //可以获取到所有的类,包括的是私有的类            //Type[] typ= ass.GetTypes();                        foreach (Type item in types)            {                Console.WriteLine(item.Name);            }            Console.Read();            //使用FileCommon的默认构造函数创建对象            object o = ass.CreateInstance("commom.FileCommon");                        Type t = o.GetType();                        //使用指定参数的构造函数创建对象            object oo = Activator.CreateInstance(t, "zs", 18);            //判断student类型的对象,是否可以赋给person。类型的引用调换            bool r = typeof(Person).IsAssignableFrom(typeof(Student));            //判断学生对象是不是某个类的实例            Student b=new Student();            Type d=typeof(Student);            bool f=d.IsInstanceOfType(b);            //判断是不是某个类的子类            bool z = typeof(Person).IsSubclassOf(typeof(Student));            #region 动态获取程序集中的属性            //GetProperties获取类型中的所有属性            PropertyInfo[] pis = d.GetProperties();            foreach (PropertyInfo pi in pis)            {                if (pi.Name == "Name")                {                    //动态给属性赋值                    pi.SetValue(b, "jk", null);                    pi.GetValue(b);                }            }             #endregion            //Type :描述类型的            //methodInfo:描述方法            #region 动态获取方法            MethodInfo[] mis = d.GetMethods();            foreach (MethodInfo mi in mis)            {                //获取子类中的扩展方法                if (mi.IsSpecialName)                {                }            }            #endregion            //动态调用Student类的SayHi方法            MethodInfo mid = d.GetMethod("Add");            mid.Invoke(d, null);                        //也可以通过获取的type类型直接调用            b.Add();        }    }    interface Person    {        int Add();    };    class Student : Person    {        public int Add()        {            throw new NotImplementedException();        }    }}</span>

 

  总结:反射其实就是另外一种创建对象的机制,只不过更灵活而已,关于以上提到的几个类,MSDN上有详细的解释,里面有很多可以用到的方法,想学习的可以查一下。



  


  相关解决方案