Crack C# namespaces in 30 seconds

The namespaces conception in C# seems to be exhaustive and insufficient at the same time compared with a strong module notation in Oberon-2 and even with a modular programming approaches 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.

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 write a main program (Print.cs) that will use the 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 run Print.exe:

$ ./Print.exe 
Hello!
Hello!

Now we will add a 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 the Print.cs with these two assemblies (reproduces Print.exe). Building an executable:

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

...and run it again:

$ ./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... However you don't need to declare it within the class, use module interface for such declarations instead!

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 :)