Morfik CSharp Data Types and Variables

In this chapter we will take a closer look at the available data types in Morfik C#, how to create new ones and how to use them in declaring variables and constants.


Data Types

In Morfik C#, every time you declare a variable you must tell the compiler what its type is. The type of a variable defines what values it can assume and what operations can be performed on it during program execution.

A type declaration specifies an identifier for the type. It is through this identifier that the type will be referenced throughout the application.

There are several different major kinds of data types. In this chapter we will review each of these kinds in detail.

Simple Types

Simple types define ordered sets of values. Let us go through the simple types that are available to Morfik C# and see how these can be an important factor in making your code clearer and more elegant.


Note: It is important to note that some of the functions designed to work with ordinal data types are not available to browser side code.


Ordinal Types

Ordinal types represent a sub set of the Simple types. All simple types which are not floating point numeric types are ordinal types which have a one to one mapping to an element of a sub set of the set of Integer values (ℤ).

Integer Types

Morfik C# offers a wide choice of Integer types. You will probably find one of them suitable for each special need. The following table shows each of the integer types which are available on the server side of your application with the range of values it can store and the format in which the value is stored.


Type Value Range Format
Shortint -128 .. 127 Signed 8 bits
Smallint -32768 .. 32767 Signed 16 bits
Longint -2147483648 .. 2147483647 Signed 32 bits
Byte 0 .. 255 Unsigned 8 bits
Word 0 .. 65535 Unsigned 16 bits
Integer -2147483648 .. 2147483647 Signed 32 bits
Cardinal 0 .. 4294967295 Unsigned 32 bits
Int64 -9.2*1018 .. 9.2*1018 Signed 64 bits
LongWord 0 .. 4294967295 Unsigned 32 bits


Due to the limitations of the data types which are supported by the JavaScript engine inside the browsers a few of these types are not available in the browser side of your application. The following table lists the Integer types available to the browser side of your application.


Type Value Range Format
Smallint -32768 .. 32767 Signed 16 bits
Longint -2147483648 .. 2147483647 Signed 32 bits
Byte 0 .. 255 Unsigned 8 bits
Word 0 .. 65535 Unsigned 16 bits
Integer -2147483648 .. 2147483647 Signed 32 bits


Note that if you declare a variable of one of the unsupported types on the browser side of your application, Morfik will generate a compiler error for it.


Note: It is important to realize that the browser side of your application, written with Morfik C#, will be compiled into JavaScript for runtime execution. Because of this, JavaScript supported types define what can or cannot be supported on the browser side.
For numeric data, JavaScript has only one data type which is the equivalent of a floating point Double. All the supported data types on the browser side must be contained within the range of values covered by a Double.

Character Type

The Char data type is used to store a single character. The character encoding which will be used is selected when you create your project.

The Char type is an ordinal type since there is a numeric value associated with each character that is represented in the type. You can obtain this value and the set of characters is ordered by it.

Enumerated Types

Enumerated types define ordered sets by enumerating the identifiers that represent its elements. The order of the elements in the set is the same in which they were declared. The presence of an identifier in the list of elements of an enumerated type is, basically, equivalent to the declaration of a constant of that type. In Listing 1 there is an example of an enumerated type which declares an element for day of week and a test sub routine showing how this type can be used.

Listing 1 – The '''DaysOfTheWeek 'enumerated type.

Enum DaysOfTheWeek {
    Sunday, Monday, Tuesday, Wednesday,
    Thursday, Friday, Saturday
}
 
Public Void test()
{
  DaysOfTheWeek ADay;
      // ...
  ADay = Monday;
      // ...
  Switch(ADay) 
  {
    Case Sunday : ShowMessage("Sunday   "); break;
    Case Monday : ShowMessage("Monday   "); break;
    Case Tuesday : ShowMessage("Tuesday"); break;
    Case Wednesday : ShowMessage("Wednesday"); break;
    Case Thursday : ShowMessage("Thursday"); break;
    Case Friday : ShowMessage("Friday"); break;
    Case Saturday : ShowMessage("Saturday "); break;
  }  
// ...
}


All enumerated type elements have a corresponding numeric value, with the first element in the enumerated type having the value of 0 and all remaining elements having a value equals to its predecessor plus one.


Note: On the server side of your application you can use the Pred and Succ functions to obtain the previous and next values in an enumerated type. You can also apply the Ord function to obtain the numeric value of an enumerated type variable.
These functions are not available on the browser side of the application. Similar behavior to that of these functions can be obtained however. For example, in order to obtain the next day in the DaysOfTheWeek set, instead of the Succ function you could use code such as this:
day = (DaysOfTheWeek)((Integer)day + 1);
More about the converting between types can be found under the topic of Typecasting in this chapter.

Boolean Type

The Boolean type is a special, pre-defined, enumerated type which is defined in the System module of the Morfik Framework. The declaration is the equivalent of the following Morfik C# enumerated type declaration:

  Enum Boolean {False, True}
Note: Since Boolean is an enumerated value it is also an ordinal type with False having the value of zero and True the value of one. On the server side of your application you can apply the Ord function to obtain the numeric value of a Boolean variable.

Subrange Types

Subrange types define ranges of values within other ordinal types. We can, for example, define a subrange type called WeekDays as being a range from the DaysOfTheWeek enumerated type that is shown in Listing 1, as an example of enumerated types. The following is an example of what such a declaration would look like:

  Typedef  Monday..Friday  WeekDays;


A variable whose type has been declared as being a Subrange type will have all the properties and characteristics of the base type of the Subrange, but will only accept values which fall within the specified range.

Floating Point Types

Floating point data types are sub ranges of the set of Real Numbers (ℝ). Morfik C# supports several different floating point types, each of them stored in a different manner/format. The following is a table of the supported data types and their capacities.

Type Range Significant Digits Size in Bytes
Single 1.5*10-45 .. 3.4*1038 7-8 4
Double 5.0*10-324 .. 1.7*10308 15-16 8
Extended 1.9*10-4951 .. 1.1*104932 19-20 10
Currency -922337203685477.5808 .. 922337203685477.5807 19-20 8


Note: It is important to realize that the browser side of your application, written with Morfik C#, will be compiled into JavaScript for runtime execution. Because of this, JavaScript supported types define that can or cannot be supported on the browser side.
For numeric data, JavaScript has only one data type which is the equivalent of a floating point Double. All the supported data types on the browser side must be contained within the range of values covered by a Double.

String Type

The string type is used to store a list of characters as if to store a word or a sentence. We can think of this type as an ordered list of characters since the composing characters are stored in the precise order in which they were stored. The following are examples of declaring variables of the string type.

  String  Str;
  String  Str2 = "Hello!  This is a string!";


You can assign values to a string variable by assigning it a list of characters surrounded by a pair of the double quote characters. Since double quotes are used to delimit the characters that are being assigned to the string variable, having a double quote character within the character list becomes a problem as the compiler would interpret it as being the end of the character list. To work around this small problem, Morfik C# allows you to prefix the double quote chararacter with a backslash indicating that it is to be interpreted literally and not as a delimiter. The following is an example of how to embed a double quote in the value assigned to a string variable:

  String  s1 = "this is a \" double quote";

String Constants

You can declare simple string constants or typed string constants. Typed Constants are functionally equivalent to initialized variables. The following are some samples of string constant declarations.

  Public const Str1 = "Hello";
 
  Public const String  Str2 = "Hello";

Structured Types

Structured types are types which store more than one atomic value. This essentially means that we are storing more than one value within a single variable. Morfik C# allows you to create structured types which have other structured types within their definition.

Arrays

Arrays are a structured data type which holds a fixed number of elements of a same type, called the base type. Arrays are ordered lists and can be accessed by a numeric index which will refer to one specific entry in the array. Morfik C# allows any range of numbers to be specified as the indexer of the array. The following are some sample declarations for arrays types in Morfik C#:

      Typedef Integer[0..10] TZeroBasedIntegerArray;
 
      Typedef Integer[1..10] TOneBasedIntegerArray;


In the first declaration we are actually specifying an array with eleven elements numbered from zero to ten.

The following are some sample declarations of array variables in Morfik C#:

      TZeroBasedIntegerArray A1;
 
      TOneBasedIntegerArray A2;
 
      Integer[2..6] A4;


Notice that you can directly define a variable as being an array or define it as being of a pre-defined array type such as the ones presented in this topic.

Once the array variables have been declared you can access the individual array elements by indexing the variable with the appropriate value such as shown in the following example:

    A1[0] = 1;
 
    A2[1] = 10;

Structs

Struct is the name we give to structured types which allow us to store multiple elements of information, with different data types, within a single variable. The declaration of a struct includes an identifier for the type and identifiers and types for each of the elements that compose the struct. Frequently the component elements of a struct are referred to as fields, much as instance variables of a class are. The following is an example of a struct declaration:

  Public Struct TPersonalData {
    String Name;
    String Phone;
  }


Structs can also be declared with an added "packed" modifier which instructs the compiler to optimize memory usage, instead of prioritizing performance. The previous declaration would then be as follows, if we added the packed modifier.

type 
  Public packed Struct TPersonalData {
    String Name;
    String Phone;
  }


You can access a field of a struct by using the same "." (dot) notation which is used for objects as show in the following example:

  Void test()
  {  
      TPersonalData Client1;
    //... 
    Client1.Name = "John";
    //...
  }

Classes

Classes are structured types very similar to structures, in many ways. Classes however can "inherit" fields from other classes and can have procedures and functions as elements.

  Public class TPersonalData {
    String Name;
    String Phone;
 
    Public Void ChangeName(String ANewName) {} 
    Public Void ChangePhone(String ANewPhone) {} 
 
  }


We will see classes in much greater detail in Chapter 17 – Object Oriented Programming with Morfik C#.

Sets

This type, defined by the Set keyword is exactly what its name implies – a set of values which consists of a subset of the values that can be assumed by the base type.

Morfik C# not only implements this type, but a full range of operations which can be handled on this data type.

The following is a declaration of a Set data type which is based on integer type:

  Typedef Set Of Integer TIntegerSet;


Literal values can be assigned to Set variables in a very simple and straightforward manner, as shown in the following example:

Listing 2 – Set declarations and operations

using SystemUtilities;
 
namespace Sets
{
 
Typedef set of Byte TByteSet;
 
TByteSet S1;
 
  Public Void Go(){
    Set Of Byte S2;
    //...
    S1 = [1,2];
    S2 = S1 + [1,3];
    S2 = S1 - [1,3];
    S2 = S1 * [1,3];
    //...
    If (S1 >= S2) {ShowMessage("superset");}
    If (S1 =  S2) {ShowMessage("equal");}
    If (S1 <> S2) {ShowMessage("unequal");}
    If (3  In S2) {ShowMessage("member");}
  }


Note: The Set type allows the usage of operators which treat Sets in a special way. In this example you can see Sets being added together or subtracted from one another.
These set operations will result in new sets which will hold all the elements of the two sets, in case of addition or a set with the elements of S1 which are not in S2, in case of subtraction, for example.

File Types

File types represents a linear sequence of values saved into a file. File types are available only on the server side of a Morfik application.

Typed Files

File types are declared with a base type which can be just about any fixed size type that can be declared in Morfik, leaving out other File types and dynamically allocated types such as classes and pointer types. This data type is frequently referred to as a "typed file" since it references a particular data type (the base type).

Listing 3 – Usage of the a typed file data type.

namespace FileTypes
{
 
Typedef File Of Integer TIntegerFile;
 
TintegerFile F1;
 
  Public Void Go() {
    File Of Integer F2;
    AssignFile(F1, "c:\test.int");
    Rewrite(F1);
    Write(F1, 9);
    CloseFile(F1);
  }
}


Binary Files

You can also work with binary files, which could be considered a special case of the Type Files where the base type is Byte. These files are normally used for lower level I/O operations and everything that goes in and out of them is seen as nothing more than a stream of bytes. The following would be a declaration of such a binary file.

  File Of Byte MyFile;

Pointers

Pointers store the memory address of other variables. Most of the time pointer variables will hold the address of a dynamically allocated variable.

The following are examples of pointer type declarations, which reference different data types, including a structure.

  Struct TPersonalInfo {
    String Name;
    String Phone;
  }
 
  Public Typedef TPersonalInfo[1..10] TPersonalInfoList;
 
  Public Typedef Integer* PInteger;
  Public Typedef TPersonalInfo* PClient;
  Public Typedef TPersonalInfoList* PClients;


Notice that pointer data types use the asterisk "*" symbol to indicate that they are actually a reference to a variable of the base type specified. It is this variable which actually holds a value of the base type used in declaring the pointer.

Listing 4 – Example of pointer usage.

Namespace Pointers
{
//The next line declares a pointer to an Integer variable
 
  Typedef Integer* PInteger;
 
  PInteger Ptr1; 
 
  Public Void Test() {
    Integer I1, I2;
    Integer* Ptr2;
    I1 = 1;
    I2 = 2;
    Ptr1 = &I1; //Assign to variable Ptr1 the address of I1
    Ptr2 = &I2; //Assign to variable Ptr2 the address of I2
    //The next line Assigns to I1 the sum of I1 and I2
    I1 = *Ptr1 + *Ptr2;
  }
}


Note: Note that in the example in listing 4 variables Ptr1 is declared as being of type PInteger and Ptr2 is defined as Integer*. These types are essentially the same since PInteger is declared as being Integer*.

The Pointer Type

In Morfik C# you can declare a variable as being of a type called Pointer. The pointer type is a generic type, not bound to any base type. It holds a memory address and makes no assumptions about what is stored in that memory position. The following is an example of a Pointer type variable.

 Pointer Ptr;

Null

When a Pointer type variable needs to be "empty" or null, Morfik C# actually provides a predefined value called Null. Null is essentially a null (empty) pointer, a pointer that does not point to any memory location.

Delegates

A delegate is essentially the same thing as pointer to a function or to a method. Delegates are very useful; in fact it is through them that the Morfik Framework handles events generated by the controls in Forms.

The way in which you declare a delegate is very similar to writing the header of a function or sub routine, as you can see in the following example:

 Public delegate Void TNotifyEvent(Sender TObject) of object;
 
 Public delegate Void FuncType (Str string);


In Listing 5 you can see an example of how to declare delegates, how to assign values to them and how to use them in calling a function.

Listing 5 – Example of delegate usage.

using SystemUtilities;
 
Namespace FunctionTypes
{
 
  Public class TestClass {
    Public Void TestProc(TObject Sender){
      //...
    }
  }
 
  Public delegate Void TNotifyEvent1(TObject Sender) of object;
  Public delegate Void FuncType(String Str);
 
Public Void MsgFunc(String Str){
  ShowMessage(Str);
}
 
  TNotifyEvent1 N1;
 
  Public Void Test{
    TestClass T;
    Void delegate(TObject Sender) of object N2;
    FuncType MsgProc;
 
    N1 = T.TestProc;
    N2 = T.TestProc;
    MsgProc = MsgFunc;
    MsgProc("Hello");
  }
 
}


In two variables declared in the example in Listing 5, you can see that the first one as the keywords "of object" added at the end of the line. The same is true of the delegate local variable declared inside the Test function. Delegates declared with "of object" are references to methods, while those declared without it are references to common procedures or functions.

Variables

A variable is an identifier (a name, if you will) that we assign to a specific memory location whose content can be altered. Variables can be defined as being of a standard or user-defined data type.

Variable Declarations

In Morfik C# variable declarations must come at the start of a function or method. All variables must be declared before the first line of code which is part of the body of the function or method.

Variables can be declared one at a time or several at a time. The following sample shows you both styles of declarations.

    Integer Int1;
 
    Integer Int2;
 
    String Str1, Str2, Str3;


Variables can also be declared with their initial values as shown in the following example.

    Integer Int3 = 10;
 
    String Str4 = "Hello";


Note: Initialized variable declarations will not work for local variables if you have selected to use Delphi as your backend platform compiler. In this case you can only have global initialized variables.

Variable declarations can have inline structured type declarations in them as can be seen in the following example.

  Struct {
    String Name;
    String Phone;
  } APerson;

Qualifiers

A reference to a variable may contain one ore more qualifiers which alter the meaning of the identifier. Qualifiers may assume several different forms and in your contact with Morfik C# through out this guide you have already had contact with them. Some examples of using qualifiers are:

You can see some usages of qualifiers in the following sample:

  TestClass TestObj;
  //...
  N1 = TestObj.Name;
  A2[1] = 10;
  I1 = *Ptr1 + *Ptr2;


In all the cases shown in the sample, the meaning of an identifier is changed by a prefix, and index or an operator (asterisk (*) – dereferencing operator).

Typecasts

Typecasts are a way to tell the compiler that you want it to temporarily treat a variable as if it were of a different type. Typecasts can be accomplished using the name of the type you want the compiler to consider as the type of the variable within parenthesis, in front of the variable’s name. The following is a small sample of using a typecast to convert an integer to a pointer and a pointer to an integer.

  Public Void test() {
    Pointer P;
    Integer I;
 
    I = (Integer)P;
    P = (Pointer)I;
    //...
  }


Note: No verification is done by the compiler regarding the properness of a typecast. It is presumed that the developer knows what he is doing when a typecast is requested.

Wrapping it up

Morfik C# has a complete and sophisticated system for handling data types. In most respects, while programming in Morfik C# and experienced C# Developer, should feel confortable in working with Morfik C#.


Related Topics

See Also

Back to top