Technically, there aren't any namespaces in the DLL.
On CLR level, there are no namespaces at all, only full class names. A CLR class name can consist of an arbitrarily long sequence of any Unicode characters - e.g. @#$%
would be a perfectly fine class name, as far as CLR is concerned.
Now, by convention (CLS, to be specific), class names are restricted to certain Unicode characters (alphanumerics and _
, and a bunch of other exotic Unicode categories - see the spec for more info) and dot, and dot is used to denote namespaces. This is purely a convention between compilers (and other tools).
So, whenever an assembly references some type for any reason, it simply uses its complete CLR name, such as System.String
. But there is more - in fact, it uses a fully qualified name, which includes an assembly as well. You can see those if you look at ildasm
output - they look something like [mscorlib]System.String
, so the runtime knows where to look.
In other words, CLR really sees assembly mscorlib.dll having class System.String
, and assembly B.exe referencing that class as [mscorlib]System.String
. Your using
statement doesn't generate any code in the output DLL/EXE on its own; it's there just so that you don't have to write System.String
all the time.
It's compiler's job to translate your code saying String
, in a scope of a using System;
statement, in a project which references mscorlib.dll
, to [mscorlib]System.String
. It's all done at compile-time. The only thing CLR does at runtime is resolving mscorlib
to locate the actual mscorlib.dll on disk (and the other answer explains how exactly that happens).