zoukankan      html  css  js  c++  java
  • 什么是BCL

    原文:

    原文: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:DemoDebugdemo.exe,通过该程序的元数据得知,其引用了一个程序集名称为aa的普通程序集,引用了一个名为bb的强名称程序集,该bb.dll的强名称标识为:xx001。
    现在CLR开始搜索程序集aa,首先它会从demo.exe控制台的同一目录(也就是D:DemoDebug)中查找程序集aa,搜索文件名为aa.dll的文件,如果没找到就在该目录下以程序集名称为目录的目录中查找,也就是会查 D:DemoDebugaaaa.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

  • 相关阅读:
    解决在Pycharm中无法显示代码提示的问题
    解决在使用pip list时出现DEPRECATION
    Pycharm 有些库(函数)没有代码提示
    Oracle 11.2.0.4 For Windows 64bit+32bit 数据库
    Windows系统下oracle数据库每天定时备份
    PowerDesigner表创建脚本双引号问题
    Oracle11g 创建数据库中问题处理(必须运行Netca以配置监听程序)
    名人名言
    项目管理
    项目管理心得:一个项目经理的个人体会、经验总结(zz)
  • 原文地址:https://www.cnblogs.com/Tpf386/p/9798217.html
Copyright © 2011-2022 走看看