热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c#中using-添加引用-程序集(详解)以及与c++中include等区别

一、c#中Using无非就三个作用,引入名字空间,减少代码输入量;给名字空间或类型定义一个别名;try-catch的一种替代。二、c#中添加引用的作用是把其它程序集包含到本项目中,就好像在本项目中写的

一、c#中Using无非就三个作用,引入名字空间,减少代码输入量;给名字空间或类型定义一个别名;try-catch的一种替代。

二、c#中添加引用的作用是把其它程序集包含到本项目中,就好像在本项目中写的类一样,因为只有在一个项目中写的类才能互相识别。c#中一个项目中写的两个类是无条件相互识别的,比如在项目中写了Class1和Class2,当然这两个类的名字空间一样。在Class2的方法中可以直接定义Class1的实例(甚至输入代码过程中有智能提示)。我理解,在书写代码的过程中,每定义一个名称,这个名称(不管是类名,方法名还是属性名)一直在随着分号的结束自动添加到自己所在的程序集中的。

三、要区分using和添加引用功能并内有任何必然联系。添加引用有点相当于c++中的include,是把别的程序集中定义的类的信息让本项目识别(因此添加完引用后就有可能出现只能提示)。using表示使用了某个名字空间,完全可以从来不用using来引入名字空间,使用某个程序集中的类型时使用包含名字空间的全名,只不过这样书写起代码太麻烦。所以using引入名字空间完全是为了书写代码方便,而添加引用是为了将别人写的类导入到自己的项目中来(就好像增加了一个新写的类一样)使用。

四、c++中也有using名字空间语句,它的名字空间和c#中的名字空间完全一样,只是为了避免重名而已。C++中的include语句只起到将某些代码原样复制到所在位置。我理解由于c++不想c#中那样有程序集的概念,不会在书写代码的过程中自动把定义的类型添加到程序集中,所以书写的各个类(不同的.cpp源文件)互相不识别,需要通过include来提前声明一个表示这个类型已经定义过了(和函数声明一样),可以在其它源文件中找到。

五、我总结,C#中没有“使用前先声明”这样的说法,只有“使用前必须在程序集中能找到”这样的说法,只要存在程序集中就有智能提示。而C++中必须遵循“使用前先声明”这样的说法,只要声明过来就有智能提示。之所以这样,可能是因为C#的源代码纯是由一个个类组成的,便于组织成程序集单元。而C++中的源代码灵活性太高,不易组成固定格式的程序集或者因为历史原因没用程序集这样的概念,所以有了两者对于“先声明后使用”的区别对待。

六、补充下C#中程序集的概念:

程序集(Assembly)是组织程序的逻辑单元,我们编写好的代码最终都会被编译器编译为若干个程序集。需要指出的是程序集只是逻辑上的划分,一个程序集可以只由一个文件组成,也可以由多个文件组成。单文件程序集的所有内容都存放在一个文件中,是最简单也是最常用的类型;多文件程序集则把它的内容分别放在多个文件中。最常见的两种程序集在物理上体现为exe文件和dll文件。

程序集由程序集元数据、类型元数据、MSIL代码和资源四部分组成(这几个部分可能在不同的物理文件中),如下图

 

1、其中,程序集元数据也叫“清单”【估计为了版本控制等作用】,它记录了程序集的许多重要信息,是程序集进行自我说明的核心文档。当程序运行时,CLR仅通过这份清单就能获取运行程序集所必需的全部信息。清单主要包括如下信息:

(1)标识信息(包括程序集的名称、版本、文化和公钥等)

(2)文件列表(程序集由哪些文件组成)

(3)引用程序集列表(该程序集所引用的其它程序集

(4)一组许可要求(运行这个程序集需要的许可)

注意:我把“引用的程序集列表加粗显示”是因为,这点很重要,因为真是因为有这个因素,比如我们在主程序集main.exe中引用了A程序集a.dll,而a.dll又引入了b.dll。那么我们在添加A程序集的引用a.dll后还需不需要添加b.dll呢?原来我一直以为需要,实际上是对程序集理解错误了,不要把程序集单纯的理解就和一个cs代码文件一样,他其实是一个比cs内容更丰富的东西。实际上运行时,main.exe先加载入内存,同时分析main.exe还包括引用了哪些其他程序集,发现引用了a.dll,所以main.exe加载入内存后又紧接着加载a.dll进入内存,又分析a.dll发现引用了b.dll,紧接着又加载b.dll进入内存,但经过测试发现如果没有发现a.dll或b.dll则在程序刚开始运行时不一定出错,只有当使用到对应dll中的东西时才提示“未能加载程序集或程序集版本号不匹配之类的错误”。(有点静态链接的意思,在运行初始阶段就把所有需要的库都加载进入内存了,只不过c++的静态链接库全部被写入到了exe中,c#中没有把dll写入exe中而已。当然要实现类似动态链接那样用到那个库时才加载对应的dll则在C#中可以使用反射机制。)

另外,程序引用中的第三方控件的版本号(我这边是路径导致的)和最终生成的程序集清单所需的版本号并不相符的问题?

   .net的CLR在执行一个程序时(如.exe)时或使用一个.dll时,他会首先查看其程序集(.exe或.dll)的程序集清单,找到运行该程序所引用的程序集并加载。.net会按一定的路径搜索,加载.若加载的版本和程序清单中的不一致时就会出现类似"程序集清单定义与程序集引用不匹配"报错。【这说明程序集列表还含有版本信息,不光只有名称】

【另外,对于上面的情况,如果b.dll位于全局程序集缓存GAC中则这个b.dll并不写入到引用程序集列表中,所以不能简单的把这些dll复制到exe的输出目录中然后拷贝到其他机器上运行,因为运行时即使b.dll存在bin目录中,但仍然不载入内存,如果其他机子的GAC中没有b.dll的话就会提示缺少b.dll的错误,我在引入oracle.dataaccess.dll的时候就出现这个情况】

关于添加引用的方法和问题详见:http://msdn.microsoft.com/zh-cn/library/windows/hardware/ez524kew(v=vs.90)

 

2、类型元数据列举了程序集中包含的类型信息【比如帮助实现了书写代码时的智能提示等作用】,详细说明了程序集中定义了哪些类,每个类包含了哪些属性和函数,每个函数有哪些参数和返回值类型,等等。

 

3、MSIL是程序集中真正在运行时使用的东西,也是核心(也就是我们写的真正的代码)。也就是我们写的代码真正在运行中的体现。相比之下“列表”和类型元数据只不过是.NET帮我们自动生成的辅助信息,只不过为了运行前的一些工作便利罢了。

 

4、资源包括图像、图标、声音等资源。

 

总之,程序集是自我说明的【通过元数据这种辅助信息】,这些自我说明文档提供了运行程序集所必须的信息,这样我们就不必依靠注册表等外部信息就能运行程序。所有的信息存于一处,这种设计方式也大大简化了程序的安装过程。

需要澄清的是,命名空间与程序集并不总是一一对应的。命名空间是类名的扩展,一个程序集可以包含多个命名空间,一个命名空间也可以分布在多个程序集中。


推荐阅读
  • 本文是一位90后程序员分享的职业发展经验,从年薪3w到30w的薪资增长过程。文章回顾了自己的青春时光,包括与朋友一起玩DOTA的回忆,并附上了一段纪念DOTA青春的视频链接。作者还提到了一些与程序员相关的名词和团队,如Pis、蛛丝马迹、B神、LGD、EHOME等。通过分享自己的经验,作者希望能够给其他程序员提供一些职业发展的思路和启示。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了Composer依赖管理的重要性及使用方法。对于现代语言而言,包管理器是标配,而Composer作为PHP的包管理器,解决了PEAR的问题,并且使用简单,方便提交自己的包。文章还提到了使用Composer能够避免各种include的问题,避免命名空间冲突,并且能够方便地安装升级扩展包。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
author-avatar
柏拉图恋情
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有