首页 > 其他分享 >正确区分类集、模块和名称空间

正确区分类集、模块和名称空间

时间:2022-10-12 22:07:56浏览次数:44  
标签:引用 System dll mscorlib 名称 模块 正确区分 类集

陈铭    Microsoft C#/.NET Asia MVP

难度:4/10
.NET是面向网络应用和服务的开发平台,那么就让我们从一个简单的网络应用开始吧——虽然这并不是本章节要讨论的主题。



//hello.cs: Say Hello to the Internet



using System;



using System.Net;






namespace Effective.Csharp.Chapter1 {



public class HelloInternet {



public static void Main() {



string address = "http://www.google.com/search?q=";



string hello = "Hello, Internet";



WebRequest myReq = WebRequest.Create(address + hello);



WebResponse myResponse = myReq.GetResponse();



myResponse.Close();



}



}



}






在向互联网问好之前,我们先得编译我们的程序,因为程序里引用了System.Net,所以编译命令似乎应该这样:



csc /r:System.Net.Dll hello.cs






但是编译器很快就抱怨起来:



error CS0006: Metadata file \'System.Net.Dll\' could not be found






看来编译器没有找到System.Net.Dll文件,但怎么会呢?类库参考里分明写着WebRequest和WebResponse是在System.Net名称空间里的啊!在解决这个问题之前,我们不妨先看看下面几个概念的定义:






名称空间(Namespace):C++和Java程序员对名称空间的概念应该并不陌生,名称空间用于在逻辑上将一组功能相关的类型组织在一起,从而避免简单类型命名引起的冲突。比如,一个生物学的类库中可能会包含“树”的类行定义,而描述计算机数据结构的应用中同样需要对“树”结构进行定义。在一个没有名称空间概念的系统中,由于命名的冲突,我们将不能在同一个应用中同时使用上述两个类型库。而在.NET中利用名称空间解决这个问题轻而易举:






namespace Biology {



public class Tree {



//生物学中对“树”的描述



}



}






namespace DataStructure {



public class Tree {



//计算机数据结构中对“树”的描述



}



}






这样,只要在程序中使用“名称空间.类型名”的方式引用类型,就可以完全避免歧义:



//生物学“树”的实例



Biology.Tree tree1 = new Biology.Tree(“Pine”);



//数据结构的“树”实例



DataStructure.Tree tree2 = new DataStructure.Tree();






之所以说名称空间只是在“逻辑上”组织类型,是因为它仅仅在设计开发阶段供程序员和编译器将不同的类型区分开来。运行系统并不理会名称空间的存在,而只是简单的把名称空间看成类型名的一个部分。系统中没有与名称空间对应的目录或文件,同一个名称空间下的类型编译之后也不一定会在物理上存储在一起。




C#允许使用using语句简化名称空间的引用,using 在功能上更接近于C++的using namespace语句,而不是Java的import。它仅仅为程序员在代码中引用类型提供一种简略形式,而不是为编译器提供任何类型信息的实际存储位置,比如:



System.Console.WriteLine(“Hello”);






在没有命名冲突的情况下完全等价于:



using System;







Console.WriteLine(“Hello”);






即使是存在命名冲突的情况下,使用using语句也可以极大的简化冗长的名称空间的引用。例如,在System.Windows.Forms和System.Web.UI.Controls两个名称空间中都存在名称为Button的类,如果在同一个项目中我们必须同时使用这两个类(事实上通常情况下很少会在同时引用这两个类,这里仅为说明问题),可以这样写:



using WinForm=System.Windows.Forms;



using WebForm=System.Web.UI.Controls;






WinForm.Button winbtn = new WinForm.Button();



WebForm.Button webbtn = new WebForm.Button();






那么既然名称空间不能提供实际类型信息存储的位置,编译器是如何取得这些类型信息从而完成编译的呢?.NET又是如何在物理上把各种类型组织在一起的呢?为此,.NET引进了类集(Assembly)概念。






类集(Assembly):类集是.NET中相关类型的物理组织形式。它是进行应用程序部署、版本控制、重用和权限分配的基本单位。类集包含了类集清单(Manifest)、在类集中定义的类型信息(Metadata)、类方法的实现代码以及其他资源。类集可以由一个或多个文件组成,这些文件或者包含资源数据,或者是包含类型信息和实现的PE格式文件。



包含了类型信息和实现的PE格式文件称为一个模块(Module),模块是运行时类型加载的基本单位。如果程序引用了模块中的某个类,那么CLR将会将整个模块加载到内存中。关于如何有效分割模块提高程序性能的更多信息,请参考条款X。






类集清单(Manifest)包含了类集层次上的信息元数据,例如类集的名称、版本以及它所包含的文件等。类集清单必须完整的保存在类集的一个模块当中,如下图所示:








在编译C#程序的时候,编译器要求必须指明在哪些类集中查找当前程序引用的类型,例如:System.Console类的实现包含在mscorlib类集中,那么编译一个引用了System.Console的程序的编译命令为:



csc /r:mscorlib.dll myprog.cs



其中,/r:引用的mscorlib.dll是mscorlib类集中包含类集清单的模块。(事实上对于mscorlib类集并不需要特别引用,稍候将会介绍)






类集与名称空间的关系



.NET文档中对两者关系的描述是:“名称空间在概念上与类集成正交关系”。用更通俗的话说,它们之间没有任何直接联系。一个名称空间中的类可能分布在几个类集当中,一个类集也可能包含几个不同的名称空间中类的实现。系统类库中确实存在很多同名的类集和名称空间,但那只能说是命名上的巧合罢了。



下表列出了常用的名称空间以及它们的实现类集之间的对应关系:







名称空间


对应的类集



System


mscorlib, System



System.IO


mscorlib, System



System.Xml


System.Data, System.Xml



System.Data


System.Data



System.Net


System



System.Reflection


mscorlib,



System.Security


mscorlib,



System.InteropServices


mscorlib,



System.Runtime.Remoting


mscorlib,



System.Runtime.Serialization


mscorlib,







这里我们看到System.Net名称空间的实现包含在System类集中,所以要正确编译本章开始提及的程序,我们必须在编译命令中引用System类集而不是System.Net:



csc /r:System.Dll hello.cs



程序顺利编译通过。




TIP:在.NET Framework文档中,我们可以轻松的找到具体类型所属的名称空间、类集。例如,文档Console类的概述部分包含了如下信息:



public sealed class Console




Requirements
Namespace: System ß 类型所属名称空间



Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows .NET Server family



Assembly: Mscorlib (in Mscorlib.dll) ß 所属类集


似乎故事至此应该告一段落了,但是——稍等片刻:既然我们必须向编译器指出程序中需要引用的类集,为什么编译一个引用了System.Console类的程序并不真的需要加上/r:mscorlib.dll?为什么有时候引用了System.Xml名称空间的类型却并不需要加上/r:System.Data.Dll或者/r:System.Xml.Dll呢?






这里有两种不同的情形:mscorlib类集在.NET类库中的地位非常特殊,所有的内建类型都定义在这个类集中,而且.NET类继承体系的根类Sytem.Object也定义在这个类集当中。几乎所有的应用程序都必须引用这个类集,所以C#编译器在编译过程中会自动加上对mscorlib类集的引用。



另外,C#编译器允许使用配置文件来简化编译参数的设置,例如将如下内容保存到C#配置文件MyExe.rsp:



#注释:编译source1.cs source2.cs,生成MyExe.exe
/target:exe /out:MyExe.exe source1.cs source2.cs



然后就可以通过制定配置文件的方式来编译MyExe程序了:



csc @MyExe.rsp






需要引用的类集也是配置文件的内容之一,可以在配置文件中指定程序需要引用得类集。鉴于一些类集在编写程序的过程中比较常用,C#的设计者将这些类集的引用放在了C#编译器的缺省配置文件当中,该配置文件位于%SystemRoot%\\Microsoft.Net\\Framework\\%version%\\csc.rsp,其中%SystemRoot%是Windows的安装目录,而%version%是.NET Framework的版本号。该文件的内容如下:



# This file contains command-line options that the C#



# command line compiler (CSC) will process as part



# of every compilation, unless the "/noconfig" option



# is specified.






# Reference the common Framework libraries



/r:Accessibility.dll



/r:Microsoft.Vsa.dll



/r:System.Configuration.Install.dll



/r:System.Data.dll



/r:System.Design.dll



/r:System.DirectoryServices.dll



/r:System.dll



/r:System.Drawing.Design.dll



/r:System.Drawing.dll



/r:System.EnterpriseServices.dll



/r:System.Management.dll



/r:System.Messaging.dll



/r:System.Runtime.Remoting.dll



/r:System.Runtime.Serialization.Formatters.Soap.dll



/r:System.Security.dll



/r:System.ServiceProcess.dll



/r:System.Web.dll



/r:System.Web.RegularExpressions.dll



/r:System.Web.Services.dll



/r:System.Windows.Forms.Dll



/r:System.XML.dll



这样,C#编译器在编译任何程序的时候,都会自动引用以上列出的所有类集——除非通过使用/noconfig显式指定忽略配置文件。(完)

标签:引用,System,dll,mscorlib,名称,模块,正确区分,类集
From: https://blog.51cto.com/amadeus/5751645

相关文章

  • 【机器学习实战学习笔记】之 3 决策树01(含Matplotlib模块介绍)
    目录​​一、决策树简介​​​​1、引入​​​​1.二十个问题的游戏​​​​2、决策树​​​​1.工作原理​​​​2.算法特点​​​​二、决策树的构造​​​​1、步骤​​......
  • 【PCL模块解析 07 之 点云分割】01 平面模型分割
    目录​​一、前言​​​​二、PCL简介​​​​1、PCL简介​​​​2、PCL分割​​​​三、平面模型分割​​​​1、全部代码​​​​2、分块介绍​​​​1.创建数据​​​​2......
  • 模块包学员管理系统
    一、manage.py(一)导入addstudent.py模块fromaddstudentimport*(二)创建一个主类classManage_Student(object):1、初始化属性里创建一个添加学员信息的空列表......
  • 模块化编程理念
    1.模块化程序设计理念(1)python程序由模块组成,一个模块对应python源文件,一般后缀名是:.py。(2)模块由语句组成,运行python程序时,按照模块中语句的顺序依次执行。(3)语句是python程序......
  • Qt5 使用CMake 添加QtResourceFile(qrc)资源文件和添加QT模块
    Qt:5.12.9添加资源文件CMakeLists.txt .....qt5_add_resources(qrc_FILESResourceFile.qrc)if(ANDROID)add_library(qtGUIDemo2CMake2SHAREDmain.cpp......
  • Python 远程部署利器 Fabric2 模块
    fabric 官网英文文档:​​http://www.fabfile.org/​​《Python自动化运维技术与最佳实践》如何用Fabric实现无密码输入提示的远程自动部署:fabric实现远程操作和部署:简介F......
  • Node.js 中通过 babel 体验 ES6 模块化
    A.安装babel打开终端,输入命令:npminstall--save-dev@babel/core@babel/cli@babel/preset-env@babel/node安装完毕之后,再次输入命令安装:npminstall--save@babel/p......
  • 二.模块化
    为什么需要模块化?如果没有模块化的话,那么后引入的 会代替 前引入的[a.js 有一个name,b.js有一个name那么先引入a.js在引入b.js 那么b会把a的顶替掉]......
  • 三.nodejs基础模块 http
    服务端开发--基础--采用http模块例子: //引入http模块consthttp=require('http')//要返回1.htmlconstfs=require('fs')//创建一个服务constserv......
  • Python pdb模块的使用
    野路子出生,写Python也有段时间了,一般的调试都用的print,PyCharm的debug功能也用的比较少,主要一般也用不到,第二是自己也不怎么会用. 服务器开发,本地根本没有运行的环境,......