Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is C# namespace compiled into IL files to be "complete" names?

Tags:

namespaces

c#

il

E.g, if I have

namespace a
    namespace b
{
    class C...
    class D...
}

So after compiling, in IL file, where's the namespace information? Do I get two classes named a.b.C and a.b.D where the class names is prefixed by the namespace name?

Or I get a namespace a.b in the assembly file and having class C/class D inside it, just like C# code?

like image 569
vik santata Avatar asked Dec 24 '22 18:12

vik santata


2 Answers

The CLR doesn’t know anything about namespaces. When you access a type, the CLR needs to know the full name of the type and which assembly contains the definition of the type so that the runtime can load the proper assembly, find the type, and manipulate it.

It mean that your class C in namespace b is stored like b.C.

like image 139
bot_insane Avatar answered Dec 31 '22 15:12

bot_insane


The other two responses wrote something, so I have to write the opposite :-)

Let's say that Microsoft kept the foot in both camps... Reading the ECMA-335:

Page 114

While some programming languages introduce the concept of a namespace, the only support in the CLI for this concept is as a metadata encoding technique. Type names are always specified by their full name relative to the assembly in which they are defined.

But then even this ECMA standard uses freely the namespace concept:

In order to prevent name collisions into the future, all custom attributes in the System namespace are reserved for standardization.

And the IL language supports the .namespace instruction, that is equivalent to the namespace instruction of C# (this instruction is named in the ECMA standard but there are no examples. The ILASM compiles correctly this example and the decompiled code is what one would expect)...

.namespace A
{
    .namespace B
    {
        .class public auto ansi beforefieldinit C
            extends [mscorlib]System.Object
        {
            // Nested Types
            .class nested public auto ansi beforefieldinit D
                extends [mscorlib]System.Object
            {
                // Methods
                .method public hidebysig specialname rtspecialname 
                    instance void .ctor () cil managed 
                {
                    // Method begins at RVA 0x2050
                    // Code size 7 (0x7)
                    .maxstack 8

                    IL_0000: ldarg.0
                    IL_0001: call instance void [mscorlib]System.Object::.ctor()
                    IL_0006: ret
                } // end of method D::.ctor

            } // end of class D


            // Methods
            .method public hidebysig specialname rtspecialname 
                instance void .ctor () cil managed 
            {
                // Method begins at RVA 0x2050
                // Code size 7 (0x7)
                .maxstack 8

                IL_0000: ldarg.0
                IL_0001: call instance void [mscorlib]System.Object::.ctor()
                IL_0006: ret
            } // end of method C::.ctor

        } // end of class A.B.C
    }
}

But note that the generated code is equivalent to not using .namespace and including directly the full name in the .class:

.class public auto ansi beforefieldinit A.B.C
    extends [mscorlib]System.Object
{
    // Nested Types
    .class nested public auto ansi beforefieldinit D
        extends [mscorlib]System.Object
    {
        // Methods
        .method public hidebysig specialname rtspecialname 
            instance void .ctor () cil managed 
        {
            // Method begins at RVA 0x2050
            // Code size 7 (0x7)
            .maxstack 8

            IL_0000: ldarg.0
            IL_0001: call instance void [mscorlib]System.Object::.ctor()
            IL_0006: ret
        } // end of method D::.ctor

    } // end of class D


    // Methods
    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method C::.ctor

} // end of class A.B.C

And then the Type class has a Name and a Namespace properties. And the Type class (as a big piece of mscorlib) is integral to the good working of the CLR.

So if the question is: is there an explicit namespace in a compiled .NET program? The response is "no". There is only fullnames.

If the question is: is there the concept of namespace in .NET (at any/all levels)? The response is "yes". It is present both in IL (source code level, .namespace), CLR (.NET API, Type.Namespace), C# (the "main" language of .NET, used to write nearly all the .NET libraries) (namespace).

like image 36
xanatos Avatar answered Dec 31 '22 14:12

xanatos