原文:

原文:https://www.cnblogs.com/1996V/p/9037603.html

什么是BCL

当你通过VS创建一个项目后,你这个项目就已经引用好了通过.NET下的语言编写好的一些类库。比如控制台中你直接就可以用ConSole类来输出信息,或者using System.IO 即可通过File类对文件进行读取或写入操作,这些类都是微软帮你写好的,不用你自己去编写,它帮你编写了一个面向.NET的开发语言中使用的基本的功能,这部分类,我们称之为BCL(Base Class Library), 基础类库,它们大多都包含在System命名空间下。

基础类库BCL包含:基本数据类型,文件操作,集合,自定义属性,格式设置,安全属性,I/O流,字符串操作,事件日志等的类型

System.Object的意义

说起类型,这里要说CTS定义的一个非常重要的规则,就是类与类之间只能单继承,System.Object类是所有类型的根,任何类都是显式或隐式的继承于System.Object。

System.Object定义了类型的最基本的行为:用于实例比较的Equals系列方法、用于Hash表中Hash码的GetHashCode、用于Clr运行时获取的类型信息GetType、用于表示当前对象字符串的ToString、用于执行实例的浅复制MemberwiseClone、用于GC回收前操作的析构方法Finalize 这6类方法。

所以 Object不仅是C#语言的类型根、还是VB等所有面向.NET的语言的类型根,它是整个FCL的类型根。

当然,CTS定义了单继承,很多编程语言都满足这个规则,但也有语言是例外,如C++就不做继承限制,可以继承多个,C++/CLI作为C++在对.NET的CLI实现,如果在非托管编码中多继承那也可以,如果试图在托管代码中多继承,那就会报错。我前面已经举过这样特殊情况的例子,这也在另一方面反映出,各语言对CTS的支持并不是都如C#那样全面的,我们只需明记一点:对于符合CTS的那部分自然就按照CTS定义的规则来。 任何可遵循CTS的类型规范,同时又有.NET运行时的实现的编程语言就可以成为.NET中的一员。

程序集的加载方式

对于自身程序集内定义的类型,我们可以直接从自身程序集中的元数据中获取,对于在其它程序集中定义的类型,CLR会通过一组规则来在磁盘中找到该程序集并加载在内存。

CLR在查找引用的程序集的位置时候,第一个判断条件是 判断该程序集是否被签名。
什么是签名?

程序集搜索规则

事实上,按照存储位置来说,程序集分为共享(全局)程序集和私有程序集。

CLR查找程序集的时候,会先判断该程序集是否被强签名,如果强签名了那么就会去共享程序集的存储位置(后文的GAC)去找,如果没找到或者该程序集没有被强签名,那么就从该程序集的同一目录下去寻找。

强名称程序集是先找到与程序集名称(VS中对项目右键属性应用程序->程序集名称)相等的文件名称,然后 按照唯一标识再来确认,确认后CLR加载程序集,同时会通过公钥效验该签名来验证程序集是否被篡改(如果想跳过验证可查阅https://docs.microsoft.com/zh-cn/dotnet/framework/app-domains/how-to-disable-the-strong-name-bypass-feature),如果强名称程序集被篡改则报错。

而弱名称程序集则直接按照与程序集名称相等的文件名称来找,如果还是没有找到就以该程序集名称为目录的文件夹下去找。总之,如果最终结果就是没找到那就会报System.IO.FileNotFoundException异常,即尝试访问磁盘上不存在的文件失败时引发的异常。

注意:此处文件名称和程序集名称是两个概念,不要模棱两可,文件CLR头内嵌程序集名称。

举个例子:
我有一个控制台程序,其路径为D:\Demo\Debug\demo.exe,通过该程序的元数据得知,其引用了一个程序集名称为aa的普通程序集,引用了一个名为bb的强名称程序集,该bb.dll的强名称标识为:xx001。
现在CLR开始搜索程序集aa,首先它会从demo.exe控制台的同一目录(也就是D:\Demo\Debug\)中查找程序集aa,搜索文件名为aa.dll的文件,如果没找到就在该目录下以程序集名称为目录的目录中查找,也就是会查 D:\Demo\Debug\aa\aa.dll,这也找不到那就报错。
然后CLR开始搜索程序集bb,CLR从demo.exe的元数据中发现bb是强名称程序集,其标识为:xx001。于是CLR会先从一个被定义为GAC的目录中去通过标识找,没找到的话剩下的寻找步骤就和寻找aa一样完全一致了。

当然,你也可以通过配置文件config中(配置文件存在于应用程序的同一目录中)人为增加程序集搜索规则:
1.在运行时runtime节点中,添加privatePath属性来添加搜索目录,不过只能填写相对路径:

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="relative1;relative2;" /> //程序集当前目录下的相对路径目录,用;号分割
</assemblyBinding>
</runtime>

2.如果程序集是强签名后的,那么可以通过codeBase来指定网络路径或本地绝对路径。

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>

当然,我们还可以在代码中通过AppDomain类中的几个成员来改变搜索规则,如AssemblyResolve事件、AppDomainSetup类等。

有关运行时节点的描述:https://docs.microsoft.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/runtime-element

什么是BCL的更多相关文章

  1. BCL中String.Join的实现

    在开发中,有时候会遇到需要把一个List对象中的某个字段用一个分隔符拼成一个字符串的情况.比如在SQL语句的in条件中,我们通常需要把List<int>这样的对象转换为“1,2,3”这样的 ...

  2. 关于CLR、CIL、CTS、CLS、CLI、BCL和FCL 的区分与总结

    关于CLR.CIL.CTS.CLS.CLI.BCL和FCL 的区分与总结 如果要想深入学习.NET平台,那么标题中的这些关键字对你来说并不陌生,这些名词构成了.NET庞大的生态系统,为了宏观认识.NE ...

  3. “菜”鸟理解.NET Framework(CLI,CLR,CTS,CLS,BCL,FCL)

    既然要学.NET,就要先认识认识她,我不喜欢大段大段文字的东西,自己通过理解,画个图,来看看.NET的沉鱼落雁,闭月羞花之容. 最下层蓝色部分是.NET Framework的基础,也是所有应用软件的基 ...

  4. 关于CLR、CIL、CTS、CLS、CLI、BCL和FCL

    如果要想深入学习.NET平台,那么标题中的这些关键字对你来说并不陌生,这些名词构成了.NET庞大的生态系统,为了宏观认识.NET平台,学些.NET架构体系,针对一些常用常用名词的理解是很有必要的,未必 ...

  5. Microsoft.Bcl.Build 1.0.10 稳定版发布

    Microsoft.Bcl.Build 1.0.10 稳定版发布 解决了之前 1.0.8 在未下载相应的Nuget Package 的情况下项目无法加载的情况 但由于 Microsoft.Net.Ht ...

  6. java与C#用protobuf通信--java如何转换protobuf-net中的bcl.Decimal对象

    公司内部有些C#服务使用proto-net,引入了bcl.proto中的bcl.Decimal.bcl.DateTime等.对于java的proto生成代码需要对bcl.Decimal.bcl.Dat ...

  7. Java如何转换protobuf-net中的bcl.DateTime对象

    一.定义DateTime Message 参考文档:https://github.com/mgravell/protobuf-net/blob/master/src/Tools/bcl.proto m ...

  8. BCL和CoreFx的区别

    bcl是.netframework clr 的基础库corefx是.net core clr的基础库

  9. XP .Net 4.0使用Microsoft.Bcl需要安装XP补丁NDP40-KB2468871-v2-x86

    XP .Net 4.0使用Microsoft.Bcl需要安装XP补丁NDP40-KB2468871-v2-x86

  10. “菜”鸟理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)

    既然要学.NET,就要先认识认识她,我不喜欢大段大段文字的东西,自己通过理解,画个图,来看看.NET的沉鱼落雁,闭月羞花之容. 最下层蓝色部分是.NET Framework的基础,也是所有应用软件的基 ...

随机推荐

  1. canvas常用属性方法由浅下沉

    首先引入<canvas></canvas>标签就不必说了. 其次就是得到canvas的2d环境了( var ctx = canvasDom.getContext('2d') ) ...

  2. go加密算法:CBC对称加密(一)--DES

    package main import ( "bytes" //"crypto/aes" "crypto/cipher" "cry ...

  3. Vagrant 总结

    引言   本文将讨论Vagrant基础应用,高级应用,基于Vagrant 的虚拟机优化,Vagrant的优势及区别等四部分   参考资料: [阿里云教程中心]Docker学习总结之Docker与Vag ...

  4. Hadoop核心架构(1)

    在大数据的发展过程中,出现了一批专门应用与大数据的处理分析工具,如Hadoop,Hbase,Hive,Spark等,我们先从最基础的Hadoop开始进行介绍 Hadoop是apache基金会下所开发的 ...

  5. Apache Flume简介及安装部署

    概述 Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的软件. Flume 的核心是把数据从数据源(source)收集过来,再将收集到的数据送到指定的目 ...

  6. 帆软SQL报异常:多表连接的时候出现错误:未明确定义列

    我刚开始的代码: select dm_veh_jdcgz_mx.DAY_ID ,--日期 dm_veh_jdcgz_mx.GLBM ,--管理部门ID dm_veh_jdcgz_mx.SFZMHM , ...

  7. Java设计模式(6)——创建型模式之原型模式(Prototype)

    一.概述 概念 // 引用自<Java与模式> UML图 第二种:登记式 二.实践 先导知识 对象的拷贝: 直接赋值:此时只是相当于a1,a2指向同一个对象,无论哪一个操作的都是同一个对象 ...

  8. linux怎么把英文版火狐浏览器改成中文

    一.按alt打开菜单栏,点击help>about firefox查看自己的火狐浏览器版本 比如我的是52.4.0版本 二打开网址 http://ftp.mozilla.org/pub/firef ...

  9. 使用OpenLayers发布地图

    OpenLayers是用于制作交互式Web地图的开源客户端JavaScript类库,制作的地图几乎可以在所有的浏览器中查看.因为是客户端类库,它不需要特殊的服务器端软件或配置,甚至不用下载任何东西就可 ...

  10. 成都Uber优步司机奖励政策(2月2日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...