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