程序集和反射(C#)

时间:2021-08-28 06:20:47

这里我又唠叨几句,大家在学习的时候,如看书或者看视频时觉得非常爽,因为感觉基本都看得懂也都挺容易的,其实看懂是一回事,你自己会动手做出来是一回事,自己能够说出来又是另一回事了。应该把学到的东西变成自己的东西,而不是依样画瓢。

在说反射之前,我们先来了解一下什么是程序集?

程序集

程序集是.net中的概念,程序集可以看作是给一堆相关类打一个包,相当于java中的jar包。

程序集包含:

资源文件

类型元数据(描述在代码中定义的每一类型和成员,二进制形式)

IL代码(这些都被封装在exe或dll中)

exe与dll的区别。

exe可以运行,dll不能直接运行,因为exe中有一个main函数(入口函数)。

类型元数据这些信息可以通过AssemblyInfo.cs文件来自定义。在每一个.net项目中都存在一个AssemblyInfo.cs文件,代码格式:

using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // 有关程序集的常规信息通过以下 // 特性集控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("ReflectedDemo")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReflectedDemo")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 使此程序集中的类型 // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, // 则将该类型上的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("7674d229-9929-4ec8-b543-4d05c6500863")] // 程序集的版本信息由下面四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

这些信息在哪里体现呢?就在我们程序集的属性当中进行体现

我们平时在安装一些CS客户端程序的时候,在安装目录下面会看见许多的程序集文件。

使用程序集的好处

程序中只引用必须的程序集,减小程序的尺寸。

程序集可以封装一些代码,只提供必要的访问接口。

方便扩展。

如何添加程序集的引用?

直接添加程序集路径或者添加解决方案中的项目引用。

当我们需要扩展一个程序的时候,你可能会直接在原有的项目中进行添加,那这样的话,如果你的这些代码想共享给别人使用呢?你就可以打包成一个程序集,然后别人只要通过引用你这个程序集就可以进行扩展了。像我们常见的.net第三方框架库,如log4net、unity等等。

注意:不能添加循环引用

什么是添加循环引用?就是说A项目如果添加了B项目的项目引用,那么此时B项目不能再添加A项目的项目引用,也就是说添加项目引用时,必须是单向的,像我们常见的三层框架之间的项目引用。

反射

关于反射,你只要是做.net开发,你就一定天天在用。因为VS的智能提示就是通过应用了反射技术来实现的,还有我们常用的反编译神器Reflector.exe,看它的名字就知道了。项目中比较常见的,是通过结合配置文件来动态实例化对象,如切换数据库实例,或者Sprint.net的通过配置文件来实现依赖注入等。

反射技术其实就是动态获取程序集的元数据的功能,反射通过动态加载dll,然后对其进行解析,从而创建对象,调用成员。

Type是对类的描述,Type类是实现反射的一个重要的类,通过它我们可以获取类中的所有信息,包括方法、属性等。可以动态调用类的属性、方法。

反射的出现让创建对象的方式发生了改变,因为过去面完创建对象都是直接通过new。

dll里面有两部分东西:IL中间语言和metadate元素据。

在.NET中反射用到命名空间是System.Reflection,这里我先通过一个Demo来看反射能做些什么

1、  新建控制台项目ReflectedDemo

2、  新建类库项目My.Sqlserver.Dal

新建两个类SqlServerHelper和SqlCmd,前者为共有类,后者为私有类