原文:

原文: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. JQ中的选择器children()和find()区别

    1:children及find方法都用是用来获得element的子elements的,两者都不会返回 text node,就像大多数的jQuery方法一样. 2:children方法获得的仅仅是元素一 ...

  2. kubernetes理论基础#开始入坑啊!

    什么是kubernetes 首先,他是一个全新的基于容器技术的分布式架构领先方案.Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg).在Docker技术的基础上, ...

  3. python学习——函数进阶

    首先来看下面这个函数. def func(x,y): bigger = x if x > y else y return bigger ret = func(10,20) print(ret) ...

  4. Flask后台管理

    管理后台主页 需求 为后台主页提供专门的视图函数 需要带入当前管理员用户相关信息以便在界面进行展示 代码实现 在 modules/admin/views.py 文件中添加视图函数 @admin_blu ...

  5. (cmath)关于头文件cmath

    关于头文件cmath // -*- C++ -*- C forwarding header. // Copyright (C) 1997-2014 Free Software Foundation, ...

  6. NoSQL入门第三天——Redis配置文件与持久化

    一.解析Redis配置文件redis.conf (Linux下配置多于编码) 1.它在哪 由于我是在root的家目录下载安装的,默认的安装位置就是: conf就在这里: 根据经验,出厂的conf永远不 ...

  7. DevExpress TreeList用法总结

    http://blog.itpub.net/29251214/viewspace-774395/ http://blog.csdn.net/czp_huster/article/details/501 ...

  8. JetBrains Makes its Products Free for Students(JetBrains 对学生免费了)

    只要你有大学有些 后缀是 .edu的  如:@buaa.edu.cn,用你的邮箱注册,就可以免费试用 JetBrains了 下面是详细注册步骤: Hello everyone, If you’re o ...

  9. HBase 数据的多版本特性潜在的意外

    HBase做为KeyValue结构存储,在存储上是依照RowKey的字典序进行排序,对于很多应用而言这可能远远不够,好在HBase的数据可以存储多个版本,并且版本可以排序,其理论上最大的版本数目Int ...

  10. hugepages_settings.sh

    #!/bin/bash## hugepages_settings.sh## Linux bash script to compute values for the# recommended HugeP ...