首页 > 代码库 > 浅析C#种的反射

浅析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上有详细的解释,里面有很多可以用到的方法,想学习的可以查一下。



  



浅析C#种的反射