John K
John K

Reputation: 28897

Does C# 4 optimize away namespaces in a manner that previous C# versions did not?

This question is for interest sake. I'm working with a third-party library and came across the following documentation on a CMS.Security.Dummy class:

DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping entire namespace under .NET 4.0.

Does anybody know, or can anybody speculate why .NET 4 would drop the namespace if the dummy class were removed?

Because .NET 4 is explicitly named in the source code comment, I assume previous C# versions exhibit behaviour that do not require this dummy class. That's purely speculative though.

Screen shot

documentation

Decompiled Source Code

#region Assembly CMS.SettingsProvider.dll, v4.0.30319
// ...\solution\wwwroot\Bin\CMS.SettingsProvider.dll
#endregion

using System;

namespace CMS.Security
{
    // Summary:
    //     DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping
    //     entire namespace under .NET 4.0.
    public class Dummy
    {
        // Summary:
        //     DO NOT DELETE THIS CLASS - This class prevents the compiler from dropping
        //     entire namespace under .NET 4.0.
        public Dummy();
    }
}

Upvotes: 45

Views: 1944

Answers (3)

Eric Lippert
Eric Lippert

Reputation: 660317

A little-appreciated fact is that there is no such thing as a "namespace" from the point of view of the underlying CLR type system. Rather, it's just a convention that we say that a type that contains periods in its name is "a member of a namespace". Logically there is no difference at all between the legal code:

namespace N
{
    class C  {}
}

and the psuedo-code:

class N.C {}

C# forces you to pretend this pleasant fiction is reality, but it is just a fiction -- from the perspective of the CLR type system, of course. From the perspective of the C# compiler, of course namespaces are "real". They just don't correspond to anything in metadata other than a portion of the name of a type.

In short: if you make an assembly with an "empty" namespace then the "namespace" doesn't exist at all in the compiled binary. A "namespace" only comes into existence when there is a type in the library that has periods in its name.

Now, why you would care about ensuring that an "empty" namespace has some presence in the binary form, I have no idea.

I assume previous C# versions exhibit behaviour that do not require this dummy class

Nope. Every version of C# since 1.0 throws away empty namespaces.

Upvotes: 90

Chris
Chris

Reputation: 28064

The only semi-related issue I can think of is that when compiling a project in msbuild, indirect references are not always copied to the bin directory of the current app. If library B indirectly references library A and library C references B only, library A's output will not necessarily be copied to the bin folder when compiling library C. In the past, I've used a null field reference on a class to ensure that the dependency is explicit and the output is deployed properly. Maybe the original devs experienced something similar and this was their solution?

Upvotes: 7

Jon Skeet
Jon Skeet

Reputation: 1502226

Given that the namespace doesn't contain any members (without that class), I'm not sure there's even the concept of a namespace at that point... nor would I expect it to be useful anyway.

I've just tried to reproduce this with the C# 2 compiler, and I can't see any trace of an empty namespace within the IL.

Upvotes: 23

Related Questions