C#中DLL与命名空间的关系

这里的高级问题:

今天我花了很多时间在基础高级概念上进行自我教育,例如API,静态和动态库,DLL和C#中的编组。 获得所有这些知识使我看起来像一个非常基本的问题,并可能在我对这些概念的理解中表现出一个漏洞:

我知道的:

  • DLL可能包含类,而这些类又包含各种类成员,例如方法和字段,其中一些我可能希望在我的程序中使用
  • 在C#中,我们在代码顶部使用关键字“using”来定义我们想要包含在程序中的命名空间

我得不到的:

我的印象是实际的方法是在DLL中定义的。 当我给出的所有函数都是命名空间时,我的程序如何找到DLL中定义的实际函数? 在顶部“使用XYZ.dll”而不是“使用XYZ_namespace”对我来说似乎更直观。

非常感谢帮助我填补这里的空白。

编辑:修改后的post特定于C#。

编辑2:对于其他想知道他们的C#应用​​程序如何通过“使用namespaceX”实际获得类型的人来说,这是一个很好的资源(除了下面的有用post): http://broadcast.oreilly。 com / 2010/07 / understanding-c-namespaces-and.html

基本上,您要使用的类型驻留在库中,您必须将Visual Studio设置为引用这些库,以便可以在代码中“使用”其命名空间。

在C#中,DLL(也称为程序集)包含class es(和其他类型)。 这些类型通常具有长全名,如System.Collections.Generic.List 。 这些类型可以包含方法。

在“ References区域中,您有对程序集的引用(这是.csproj文件的一部分)。 在.cs文件中,您不需要包含任何用于引用此DLL的用法,因为它已在.csproj文件中引用。

如果你包括一个像using System.Collections.Generic;的行using System.Collections.Generic; ,它告诉C#编译器在键入List时查找System.Collections.Generic.List List 。 但是,您不需要这样做:只需键入System.Collections.Generic.List

DLL包含我们可能希望在程序中使用的许多例程/方法

部分正确。 .Net DLL包含类 ,这些类包含成员 (字段,常量,方法,属性,事件,运算符,索引器)。

.Net严格来说是OOP,它不允许代码“浮动”。 一切都在课堂内定义。

在命名空间中组织类只是为了保持命名分离和组织。 将名称空间视为包含一个或多个类的“文件夹”,并且可以在一个或多个程序集(DLL)中定义。

例如, System命名空间内的类在2个程序集(DLL)中定义: mscorlib.dllSystem.dll

同时,这两个程序集包含许多不同的命名空间,因此您可以将Assembly to Namespace关系视为多对多关系。

当您在C#代码文件的开头放置using指令时,您告诉编译器“我想使用此 Namespace 定义的类无论它们来自哪个程序集” 。 您将能够在当前项目中引用的所有程序集中使用此类命名空间中定义的所有类。

我的印象是实际的方法是在DLL中定义的。 当我给出的所有函数都是命名空间时,我的程序如何找到DLL中定义的实际函数?

通过静态或动态绑定以及程序集绑定来查找正确代码的过程。 编译代码时,静态绑定会告诉您是否编写了错误代码或忘记添加引用:

ClassInADifferentAssembly.M(); //通常这会静态绑定并在忘记包含对DifferentAssembly的引用时导致编译器错误

除非你正在处理dynamic或reflection,否则你有静态绑定。 assembly绑定是一个不同的过程。 整个过程很复杂 ,但基本上是在GAC,当前位置发现程序集,或者您甚至可以自己处理事件AppDomain.AssemblyLoad

因此,当您添加using statement静态绑定可以在上下文中成功找到正确的代码。 但是,如果稍后程序集无法在运行时绑定,您仍会收到运行时错误。

DLL是动态链接库的缩写。 并且可以是包含类,方法等的类库,这些类都可以放在不同的名称空间下。

首先,您必须将DLL的引用添加到项目中。 完成后,您可以使用诸如“using”之类的关键字来基本缩短到达该特定命名空间中的方法/类的路径。

示例命名空间

 Namespace.Something.SomethingMore.Finally.Just.One.More Namespace.Something.SomethingMore.Finally.Just.One.More2 

要访问这些命名空间下的类,您可以执行以下任一操作

 using Namespace.Something.SomethingMore.Finally.Just.One.More; using Namespace.Something.SomethingMore.Finally.Just.One.More2; // Now you can access classes under those namespaces without typing the whole namespace // Like in the row below Class.GetData(); 

如果您没有使用,您仍然可以访问这些类。 但那时必须打字

 Namespace.Something.SomethingMore.Finally.Just.One.More.Class.GetData(); Namespace.Something.SomethingMore.Finally.Just.One.More2.AnotherClass.GetData(); 

DLL具有一组函数。 您可以通过以下两种方式之一调用这些函数:链接DLLs导出库(lib文件)或在运行时执行链接:调用LoadLibrary()调用GetProcAddress并提供所需函数的名称。 您需要将其强制转换为实际类型(函数指针)。 通过新的函数指针调用该函数。 非常简单的东西,只需在MSDN上阅读。 C ++命名空间只是函数名称的一部分。 您可以使用名为Dependency Walker的工具查看从DLL导出的函数。