A Namespace is a prefix to item names that provides a logical grouping of types and other .Net elements, making it easier to structure together items that have a common purpose and avoid naming conflicts. Due to the vast amount of libraries and classes available in .Net (in System and third-party libraries and in every application written in .Net), using simple small names without a namespace would have led to a lot of naming conflicts, making it impossible to distinguish between each other. For example, there's a type named "Button" (representing a Button control) in the Windows Forms system library, another for WPF, another one in the VOSDK GUI classes, and of course the new typed VOSDK GUI classes library has one, too. Furthermore, it's very likely that dozens of other custom control libraries include a same named type as well! In order to distinguish among all them, an additional prefix name (namespace) has been added to each version of the type:
•System.Windows.Forms.Button // Windows forms
•System.Windows.Controls.Button // WPF
•VO.Button // VOGUI library
•XSharp.VO.Button // Typed SDK GUI library
For the full class name System.Windows.Forms.Button, everything before the final dot (System.Windows.Forms) is called the namespace of the class, while the rest is called the short class name. Note that a namespace is not something concrete, and it does not exist as a separate entity in .Net assemblies. It is only a convention to use a descriptive name prefix for all class names and is not mandatory. Using the dot as name part separator is also a convention in .Net, even though it would have been equally valid to choose another character, such as an underscore, for the same purpose, resulting in the name System_Windows_Forms_Button for the winforms class name, where "System_Windows_Forms" would have been the namespace part of the name.
Also by convention, namespace and type names are usually structured in the following format:
<Company name>.<Library name>.<Optional further group names>.<Short type name>
This has been applied in the name XSharp.VO.Button, where "XSharp" is the company name, "VO" represents the library and "Button" is the actual class (short) name. The optional additional group names provide further better structuring of the type names, often used in large libraries where it is important to logically group together the large amount of available items.
In X#, there are several ways to provide a namespace to types/classes defined in the code. The most common way is to use the BEGIN...END NAMESPACE block statement:
BEGIN NAMESPACE OurCompany.CommonLibrary
CLASS GeneralUseType
// ...
END CLASS
END NAMESPACE
Every type defined inside the block will automatically have its name prefixed by the compiler with the provided namespace, so the class in the example above would become OurCompany.CommonLibrary.GeneralUseType. Additionally, BEGIN NAMESPACE blocks can be nested (to any level), and the above could have been equally been written as follows:
BEGIN NAMESPACE OurCompany
BEGIN NAMESPACE CommonLibrary
CLASS GeneralUseType
// ...
END CLASS
END NAMESPACE
END NAMESPACE
Another option is to provide the namespace part of the name in the class declaration directly:
CLASS OurCompany.CommonLibrary.GeneralUseType
// ...
END CLASS
Finally, it is possible to define a Default Namespace in the project properties (which maps to the -ns compiler option). When defining this, all class names in the code that have not been explicitly assigned a namespace, automatically get the one provided in the project option. This is particularly useful for applications and libraries ported from Visual Objects or other systems not supporting the concept of namespaces, so all types in them used simple class names. To avoid having to explicitly provide namespace names in a large number of code files, the project option can be used instead.
Typically, in order to use a type in code, its full class name (including the namespace part) needs to be used:
FUNCTION Start() AS VOID
LOCAL oUse AS OurCompany.CommonLibrary.GeneralUseType
oUse := OurCompany.CommonLibrary.GeneralUseType{}
If the namespace part was not included, the compiler would not be able to resolve the class name. However, since always using such long names can be tedious and may lead to code bloat, it is common practice to specify commonly used namespaces at the beginning of each code file in USING statements:
USING OurCompany.CommonLibrary
FUNCTION Start() AS VOID
LOCAL oUse AS GeneralUseType
oUse := GeneralUseType{}
The USING statement instructs the compiler every time it finds a class name that it cannot resolve, to try resolving it by prefixing it with all the namespace names provided in USING statements in the given file. Of course, if multiple types used in the code have the same short name with different namespaces, it is not possible to have a USING statement for each one of them, as that would lead to a name conflict, making it impossible for the compiler to distinguish which exact class is used in each case.
Also note that any code between a BEGIN...END NAMESPACE statement, additionally automatically resolves short type names defined in it to full type names using the namespace provided in the statement. Therefore, it is not necessary to provide a namespace in the class name in this code:
BEGIN NAMESPACE OurCompany.CommonLibrary
CLASS GeneralUseType
END CLASS
CLASS AnotherClass
METHOD Test() AS VOID
LOCAL oUse AS GeneralUseType // not necessary to provide the namespace
oUse := GeneralUseType{}
END CLASS
END NAMESPACE
Especially for libraries with the Default namespace option (see above) provided, it is possible for applications that reference them to use their classes with their short names without needing to provide USING statements. This can be done by enabling the Enable Implicit Namespace lookup project option (which maps to the /ins compiler option). Every such library includes its default namespace as information in an assembly attribute and when that option is used, the compiler automatically resolves type names also by using that default namespace in the library. This is used in the VOSDK classes for example, so that all classes defined in those libraries can be used without the need to provide USING VO statements, in all files of the applications that reference those libraries.