Crack C# namespaces in 30 seconds

The namespaces conception in C# seems exhaustive and insufficient at the same time in comparison with strong module notation like in Oberon-2 and even with modular programming like in Free Pascal/Delphi.

Why insufficient? You cannot declare constants and functions within namespaces but you should add a class with constant field or static method for it. It's really sad...

Why exhaustive? The "using" directive with such introduced classes is the source of unexpected errors. Here is an example below.

I use mono C# compiler "mcs" (Mono C# compiler version 3.2.8.0, .NET 4 support) so you need rename "mcs" to "csc" on Windows.

Source file "Hello.cs"

// Hello.cs
namespace Hello 
{
  public class A 
  {
    public class В
    {
      public static string С = "Hello!";
    }
  }
}

Compile it as assembly (produces Hello.dll):

mcs /target:library Hello.cs

Now, main program (Print.cs) will use this assembly

// Print.cs
using Hello;
 
namespace MyApp
{
  class Print 
  {
    static void Main() 
    {
      System.Console.WriteLine(Hello.A.В.С);
      System.Console.WriteLine(A.В.С);
    }
  }
}

Building an executable (produces Print.exe):

mcs /reference:Hello.dll Print.cs

And then running Print.exe:

$ ./Print.exe 
Hello!
Hello!

Now add second assembly to the program. The file is A.cs

// A.cs
namespace A
{
  public class В 
  {
    public static string С = "Good bye...";
  }
}

Compile it as an assembly too (produces A.dll):

mcs /target:library A.cs

Now recompile our Print.cs with these two assemblies (reproduces Print.exe). Building an executable:

mcs /reference:Hello.dll,A.dll Print.cs

And running it another time:

$ ./Print.exe 
Hello!
Good bye...

Surprised? Sure, in real project with thousand dependencies and "using" it will be not amazing.

Such situations are not possible in Oberon-2 and other languages there you must specify module name. It is possible in Delphi/Free Pascal but you can use constants and function of the module (unit)!

program Print;
 
uses
  Hello, A;
 
begin
  writeln(Hello.B); // It's a constant B from unit Hello
  writeln(A.B); // It's a constant B from unit A 
end.

Unfortunately, if you declare B as the public constant of class A in the unit Hello, you will get the same problem as in C# above...

But you don't need to declare it within the class, use module interface for such declarations!

unit Hello;
 
interface
 
const
  B: string = 'Hello!';
 
type
  A = class
  public
    // Never use public constants of class but of unit only !!!
    const B: string = 'Hello!'; // This was impossible in Delphi 7...
  end;
 
implementation
 
end.

Take care and see you later :)