Relation between DLLs and Namespaces in C#

2020-06-16 03:05发布

问题:

High-level question here:

I have spent a lot of time today educating myself on basic high-level concepts such as APIs, static and dynamic libraries, DLLs and marshaling in C#. Gaining all of this knowledge led me to what seems like a pretty basic question, and probably demonstrates a hole in my understanding of these concepts:

What I know:

  • DLLs may contain classes which in turn contains various class-members such as methods and fields, several of which I might want to utilize in my program
  • In C# we use the keyword "using" at the top of the code, to define a namespace we want to include in our program

What I do not get:

I was under the impression that the actual methods were defined in the DLLs. How does my program find the actual functions that are defined in the DLLs, when all i give them is a namespace? It seems more intuitive to me to have "using XYZ.dll" at top, rather than "using XYZ_namespace".

Thanks a lot for helping me fill in the gaps here.

EDIT: Modified post to be specific to C#.

EDIT 2: For other people that wonder how their C# application actually gets a hold of the types made available through "using namespaceX", this is a good resource (in addition to the helpful posts below): http://broadcast.oreilly.com/2010/07/understanding-c-namespaces-and.html.

Basically the type you would like to use resides in libraries and you have to set Visual Studio to reference these libraries in order to make it possible to "use" its namespace in your code.

回答1:

In C#, DLLs (aka assemblies) contain classes (and other types). These types typically have long full names, like System.Collections.Generic.List<T>. These types can contain methods.

In your References area, you have references to assemblies (this is part of your .csproj file). In a .cs file, you don't need to include any using to reference this DLL, because it's already referenced in your .csproj file.

If you include a line like using System.Collections.Generic;, that tells the C# compiler to look for System.Collections.Generic.List<T> when you type List<T>. You don't need to do it that way, however: you can simply type System.Collections.Generic.List<T>.



回答2:

DLLs contain many routines / methods we might want to use in our programs

Partially correct. .Net DLLs contain Classes, and these classes contain Members (Fields, Constants, Methods, Properties, Events, Operators, Indexers).

.Net is strictly OOP, and it does not allow code "floating in limbo". Everything is defined inside classes.

Classes are organized in Namespaces just to keep a naming separation and organization. Think of namespaces as "folders" that contain one or more classes, and that might be defined in one or more assemblies (DLLs).

For example, Classes inside the System namespace are defined in 2 assemblies (DLLs): mscorlib.dll and System.dll.

At the same time, these 2 assemblies contain many different namespaces, so you can think the Assembly to Namespace relation as a Many-to-Many.

When you put a using directive at the beginning of a C# code file, you're telling the compiler "I want to use classes defined in this Namespace, no matter what assembly they come from". You will be able to use all classes defined in such namespace, inside all assemblies Referenced from within the current project.



回答3:

I was under the impression that the actual methods were defined in the DLLs. How does my program find the actual functions that are defined in the DLLs, when all i give them is a namespace?

The process of finding the correct code occurs through static or dynamic binding and also assembly binding. When you compile the code static binding will tell you if you wrote bad code or forgot to add a reference:

ClassInADifferentAssembly.M(); //Generally this will static bind and cause a compiler error if you forgot to include a reference to DifferentAssembly

Unless you are dealing with dynamic or reflection then you have static binding. Assembly binding is a different process. The overall process is complex, but basically assemblies are discovered in the the GAC, current location or you can even handle an event yourself, AppDomain.AssemblyLoad.

So when you add a using statement then static binding can successfully find the correct code in the context. However, you can still receive a runtime error if later the assembly fails to bind at runtime.



回答4:

DLL is short for dynamic link library. And can be a class library containing classes, methods etc that can all be put under different namespaces.

So first you have to add a reference to the DLL into your project. When that is done, you then use a keyword such as "using" to basically shorten the path to reach the methods/classes in that particular namespace.

Example namespaces

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

To reach classes under those namespaces you can do either of the following

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();

If you did not have the usings, you would still be able to access those classes. But would then have to type

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


回答5:

DLLs have a collection of functions. You can calls these functions by one of 2 ways: link with the DLLs export library (a lib file) or do the link in runtime: Call LoadLibrary() Call GetProcAddress and provide the name of the function you want. You'll need to cast it to the actual type (function pointer). Call the function via the new function pointer. Pretty simple stuff, just read it on MSDN. C++ namespaces are just a part of the function name. You can view what functions are exported from a DLL by using a tool called Dependency Walker.



标签: c# .net dll