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 3rd party libraries and in every application written in .Net), using simple small names without a namespace would had 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, also 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 also dozens of other custom control libraries include a same named type, too! 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, it does not exist as a separate entity in .Net assembiles, 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, it could had been equally valid to choose another character like an underscore for the same purpose, resulting to the name System_Windows_Forms_Button for the winforms class name, where "System_Windows_Forms" would had been the namespace part of the name.

 

Also by convention, usually namespace and type names are structured in the following format:

<Company name>.<Library name>.<Optional further group names>.<Short type name>

This has been followed 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 typed defined inside the block will automatically have its name prefixed by the compiler with the namespace provided, so the class in the above sample will become OurCompany.CommonLibrary.GeneralUseType. Also BEGIN NAMESPACE blocks can be nested (to any level) and the above could had been written in an equal way like this:

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, then 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 that did not support the concept of namespaces so all types in them used simple class names. In order to avoid having to explicitly provide namespace names in potentially 100s or 1000s of files of code, the project option can be used instead.

Using types with namespaces

Normally, 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, then the compiler would not had been able to resolve the class name. But because always using such long names can be tedious and may result to all of code bloat, it is common practice to specify the commonly used namespace in each file of code in the beginning of the 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 two or more types used in the code have the same short name with different namespaces, then 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 with 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. So 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 for example in the VOSDK classes, so all the 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.