Virtual Developer Workshop: Containerized Development with Docker
Declaring namespaces at the top of your COBOL.NET code can greatly simplify coding and streamline your syntax by eliminating unnecessary namespaces in your code and the Class Repository. This is identical in concept to the using directive in C#. The using directive in C# permits the use of types in a namespace so you do not have to qualify the use of a type or class in that namespace.
In this article I will show the use of
the ILUSING compiler directive in
Micro Focus COBOL.NET. To do this, I will also provide two additional examples
of what the code would look like when not declaring a namespace so you can have
a better idea of the advantages of this feature. This very basic sample program
gets the current time, waits 5000 milliseconds, gets the current time again,
and then calculates the elapsed time. In all examples elapsedStr is defined as
a String which is a pre-defined type in COBOL.NET that equates to a .NET System.String. i.e. there is no need to
declare a namespace for it or use the Type keyword.
The code below uses the Class Repository to declare each class that will be used in the program. Each Class in the repository associates a name (think of it as an alias) to an actual Class.
In this example the Thread class, which is in the .NET Framework System.Threading namespace, is associated with the name ThreadClass.
Likewise, DateTime and TimeSpan, which are both in the .NET Framework System namespace, are associated with "DateTimeClass" and "TimeSpanClass" respectively. In the COBOL application code, it is the alias names that are actually used, not the true .NET type or class names.
class ThreadClass as "System.Threading.Thread"
class DateTimeClass as "System.DateTime"
class TimeSpanClass as "System.TimeSpan"
01 begTime DateTimeClass.
01 endTime DateTimeClass.
01 elapsedTime TimeSpanClass.
01 elapsedStr String.
set begTime to DateTimeClass::"Now"
set endTime to DateTimeClass::"Now"
set elapsedTime to endTime::"Subtract"(begTime)
set elapsedStr to elapsedTime::"ToString"()
While the Class respository makes it convenient to declare individually each Class or type that will be used in your program. It is a convention that .NET programmers in general would not be familiar with. Furthermore, if a COBOL programmer were to look at a C# or VB.NET program as an example of how to do something they would also see that this convention is not is not used and is not necessary in other .NET languages. It could also lead to using non-standard or inconsistent class and type names throughout your application code. This could make it a little more difficult for a .NET programmer to maintain the code later...i.e. always having to look in the Class Repository to see which class is actually being used.(Classes and Enumerators) to be consistent, but this is also somewhat redundant b. The actual program code would then also be using Class names or aliases that are not standard. If another person later had to maintain this code, they would always have to look in the Class Repository sections to confirm which actual type is being used.
Using a Class without declaring it in the Class Repository or declaring a Namespace
The code below uses Classes or Types without having to declare them in the Class Repository. However, because no namespace was declared, the fully qualified type including the namespace is required. Notice the use of the type keyword followed by the fully qualified type (including the namespace) to specify a type in the working-storage section or in the code.
In this example the Thread class or type, which is in the .NET Framework System.Threading namespace, is fully qualified everywhere it used by specifying System.Threading.Thread.
Likewise, DateTime and TimeSpan, which are in the .NET Framework System namespace, are also fully qualified as System.DateTime and System.TimeSpan respectively. In the COBOL application, the actual fully qualified class or type names are used including the namespace that contains the type...NOT names declared in the Class Repository.
01 begTime2 type "System.DateTime".
01 endTime2 type "System.DateTime".
01 elapsedTime2 type "System.TimeSpan".
01 elapsedStr String.
set begTime2 to type "System.DateTime"::"Now"
invoke type "System.Threading.Thread"::"Sleep"(5000)
set endTime2 to type "System.DateTime"::"Now"
set elapsedTime2 to endTime2::"Subtract"(begTime2)
set elapsedStr to elapsedTime2::"ToString"()
The downside to this technique is that it can get rather cumbersome while coding if you always have to specify the fully qualified class or type including the namespace. This takes us to our final example and the purpose of this How-To article.
Using Classes contained in Namespaces that have been declared
The code below uses Classes or Types without having to declare them in the Class Repository. However, the difference between this and example 2 is the namespaces that contain the types have been declared with the ILUSING directive. Because of this, it is not necessary to fully qualify the types in the COBOL data definitions or business logic. The type keyword is still required, but you only need to specify the Class or Type name in double quotes.
In this example the Thread, DateTime, and TimeSpan classes are used without their respective namespaces in the code. Their namespaces are declared once at the top of the program with the ILUSING directive. This is identical in concept to the USING directive in C# or IMPORTS in VB.NET. $set is a feature of the Micro Focus compiler that allows you to set compiler directives directly in the source code. In this example it is used to specify the ILUSING directive.
1st lines of the COBOL program or Class ($set begins in column 7):
01 begTime3 type "DateTime".
01 endTime3 type "DateTime".
01 elapsedTime3 type "TimeSpan".
01 elapsedStr String.
set begTime3 to type "DateTime"::"Now"
invoke type "Thread"::"Sleep"(5000)
set endTime3 to type "DateTime"::"Now"
set elapsedTime3 to endTime3::"Subtract"(begTime3)
set elapsedStr to elapsedTime3::"ToString"()
The advantages of declaring the namespaces of the types or classes used in your COBOL.NET program are:
1. Promotes streamlined coding by allowing the use of types or classes with their exact names...without having to fully specify the namespace in the name everytime those classes are used.
2. Eliminates the need to use the Class Repository to specify each individual class and type used in your program. The combination of the ILUSING directive and the Type keyword allow you to specify the exact names of types directly in your code.
3. Because naming is more consistent and standardized, it makes the classes and types in use more recognizable to other .NET programmers looking at your code.