C#中的程序集和反射

¨什么是程序集?
       .net中的dll与exe文件都是程序集(exedll的区别?)
              区别:
                 exe文件包含程序执行的入口(main函数)
                 dll文件不包含入口
       程序集是.net中的概念。
       程序集(Assembly),可以看做是一堆相关类打一个包,相当于java中的jar包(*)
¨程序集包含
      元数据:类型元数据(描述在代码中定义的每一类型和成员,二进制形式),程序集元数据(程序集清单、版本号、名称等)
      I L代码(这些都被装在exedll)
      资源文件,如图片等
 
       元数据:元数据存储在程序集中(exe或者dll文件中),元数据会对程序集自身进行描述,比如程序集中包含哪些类,那些字段,字段是什么类型的。在运行时,需要为这个类型的数据开辟多大的内存控件,都在元数据中进行了描述。(不严谨)
       IL代码:中间代码。由编译器将c#代码编译成IL代码,等程序运行时,会将中间代码转换成具体平台的机器代码。

       程序集的好处:将不同功能的代码放到不同的程序集中,比如与webconfig文件进行交互的代码放到System.configuration.dll中,与数据库交互相关代码放到System.Data.dll中,这样程序需要什么功能,就添加对相关dll的引用即可,加入将System.configuration.dll的代码和System.Data.dll都放到一个大的文件中,那么无论想添加什么功能,都会将所有代码都添加,会增加程序的大小。
 
 
反射:
     反射无处不在,我们天天在使用。Vs的智能提示,就是通过反射获取到类的属性、方法等。还有反编译工具也是通过反射实现
     反射就是动态获取程序集的元数据(提供程序集的类型信息)的功能
     反射就是直接通过.dll来创建对象,调用成员。

我们经常使用反射

比如自己定义一个Person类,在使用这个类的对象是,使用智能感知功能,可以看到类中的属性和方法名称,这就是反射。比如我们在一个项目中定义的一个类,在另一个项目中添加引用之后,在使用这个类的对象氏就可以看到此类的属性和方法。这就是将此类所在的程序集进行了反射。

 
反射的实例:
创建一个类库,其中包含很多个类,有的类是公有的,有的是非公有的。
与这个类库的同级在建立一个控制台应用程序,在这个控制台来访问类库中的类。
方法一、我们可以将类库作为引用添加到控制台应用程序中。
现在将一种,将类库的.dll(程序集)保存到内存中。
      1、Assembly这个类的LoadFile方法就可以保存到内存中。
           Assembly asm = Assembly.LoadFile(Path.GetFullPath("MyTest.dll"));
 实例:
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Assembly asm = Assembly.LoadFile(Path.GetFullPath("MyTest.dll"));
            #region 获取程序集中所有类型,包括公共的和非公共的,都可以获取
            //Type[] types = asm.GetTypes();
            //foreach (Type item in types)
            //{
            //    Console.WriteLine(item.Name);
            //}
            #endregion

            #region 只获取公共类型
            Type[] types=asm.GetExportedTypes();
            foreach (Type item in types)
            {
                Console.WriteLine(item.Name);
            }
            #endregion
            #region 获取程序集中的指定类型
            //Type typeclass1= asm.GetType("MyTest.Class1");
            //Console.WriteLine(typeclass1.Name);
            #endregion

            #region 获取程序集中某个类型的属性或者方法,不仅可以获取到类型本身的方法,还可以获取到父类的方法,还可以获取到类中属性转换成的get和set方法。
            //Type类型可以表示任何的已知的数据类型,比如类,委托,枚举,而且通过反射获取到的Type类型的对象中存储着此类型中的所有的属性,字段,方法的定义。
            //Type typeclass1 = asm.GetType("MyTest.Class1");
            //MethodInfo[] methods= typeclass1.GetMethods();
            //foreach (MethodInfo item in methods)
            //{
            //    Console.WriteLine(item.Name);
            //}
            #endregion
            #region 获取指定的方法
            ////获取程序集中某个类型的Type类型,注意类型名称必须是全名(命名空间.类型名称),Type类型可以表示任意的类型,比如类,委托,枚举等,这个类型的实例中存储着此类中的所有的方法,属性,字段等成员
            //Type typeclass1 = asm.GetType("MyTest.Class1");
            ////使用GetMethod获取到Type对象中某个方法或者属性
            //MethodInfo method= typeclass1.GetMethod("SayHello");
            ////Activator:此类就是用来通过CreateInstance方法根据Type类型创建类型实例的。
            //object obj= Activator.CreateInstance(typeclass1);
            ////通过方法的Invoke方法调用此类型中的方法。
            ////第一个参数:要调用的方法所属类型的实例,因为此方法不是静态的,所以想调用这个方法,就必须先创建此类型的一个实例。
            ////第二个参数:此方法需要的参数数组。
            //method.Invoke(obj, null);
            #endregion

            #region 调用有参数的方法
            //Type typeclass1 = asm.GetType("MyTest.Class1");
            ////使用GetMethod获取到Type对象中某个方法或者属性
            //MethodInfo method = typeclass1.GetMethod("Print");
            ////Activator:此类就是用来通过CreateInstance方法根据Type类型创建类型实例的。
            //object obj = Activator.CreateInstance(typeclass1);
            ////通过方法的Invoke方法调用此类型中的方法。
            ////第一个参数:要调用的方法所属类型的实例,因为此方法不是静态的,所以想调用这个方法,就必须先创建此类型的一个实例。
            ////第二个参数:此方法需要的参数数组。
            ////创建object类型数组,用于存储参数
            //object[] objs={"张三",20};
            ////返回值也是object类型
            //object objreturn= method.Invoke(obj, objs);
            //Console.WriteLine(objreturn.ToString());
            #endregion
            Console.ReadKey();
        }
    }
}

你可能感兴趣的:(C#中的程序集和反射)