Show/Hide Toolbars

XSharp

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.

Specifying namespaces to type names

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.

Using types with namespaces

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

Implicit namespace lookup

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.