Manipulating .NET objects
In what follows, readers who are familiar with Fortran 95 derived types and
pointers may find it helpful to draw an analogy with the following fragment of
!Stage 1: Define a derived type.
!Stage 2: Declare a Fortran pointer to a Circle.
!Stage 3: Allocate memory and use the TYPE constructor.
In FTN95 code, the keyword OBJECT is used to declare an alias for an object
whose class is defined externally (see .NET Objects).
This is equivalent to Stage 2 in the above fragment. The use of
OBJECT does not allocate memory for the object's data.
Typically classes are accompanied by one or more methods called constructors
that initialise the object's data and define its initial state. In FTN95 the
keyword NEW@ is used to allocate memory for an object's data and to call one of
Using NEW@ performs the equivalent of Stage 3 in the above
fragment. If a constructor takes arguments, these are added to the call to
NEW@ after the class name of the .NET object ("System.Object" in this example).
Note that the use of OBJECT declares a variable of Fortran pointer type
but leaves it undefined. Using NEW@ is equivalent to using ALLOCATE (i.e.
a pointer assignment) followed by a call to the constructor.
As in this example, the class name that is used in NEW@ is usually the same as
the class name that is used in OBJECT(...). However, .NET objects exist in an
inheritance hierarchy and as a result the class name in NEW@ can be one that is
derived from that used in OBJECT(...). Thus, the following code fragment is
because "System.String" is derived from "System.Object". After the call to
NEW@, OBJ is an alias for a .NET string object.
The keyword CAST@ is used when creating an alternative alias for a .NET
object as illustrated by the following fragment.
The assignment in the last line is a pointer assignment that makes STR an
alternative alias for OBJ (memory for the object has been allocated by
using NEW@ on the line before). In a Standard Fortran context the
assignment would take the form STR= >OBJ. STR and OBJ are alternative names
for the same object in memory.
N.B. Although the above fragment illustrates a principle, it does
not represent a practical method for accessing .NET strings. For further
information see .NET string type.
An exception is raised (at runtime) if you use CAST@ with incompatible
arguments (e.g. if "System.String" was not derived from "System.Object").
NEW@ can be called in the context of a call to another function. For
In this code MyRun is an alias for an overloaded static method. In
one overloaded case, it can take a single argument that
is a reference to a Microsoft Form. MyForm is assumed to be a class
defined in MyLib that is derived from the Form class. NEW@ can be used in
this context despite the fact that the argument does not provide a direct
type match. This is because FTN95 type matching permits a match with a class
that is derived from the given argument class.
In standard Fortran, P%NAME selects the data member called NAME for an
instance P of a derived type. In FTN95, the '%' operator can also be used to
access data members of .NET objects assuming that such members have meaningful
Fortran types. For example:
In this case using a second string argument for NEW@ calls a constructor that
initialises the string. Length is a data member of System.String so the value 5
(the length of "alpha") is printed. In fact Length is an example of a
particular kind of data member that is called a property. A property
is not accessed directly but via a method belonging to the class and as a
result can be made to be read-only or write-only. In this case Length is
read-only and the following fragment would fail to compile
If a simple (non-property) data member of a .NET object is passed as an
argument to a routine then (since it is passed by reference) it can be used
and/or altered by the routine. However, a property is first evaluated and
stored locally before the address of the local store is passed by reference.
Consider for example:
This code will compile and the routine FOO could both use and alter the
associated dummy argument. However, any change will not be reflected back to
STR. In other words the argument is effectively passed by value. See .NET
string type for a much easier way to use .NET strings.
It is important to realise that Fortran variables are not case-sensitive. All
names are converted by the compiler to upper case (only characters within
quoted strings are case-sensitive). Thus STR%Length is exactly the same as
STR%LENGTH. The compiler uses a case-insensitive search when it looks for a
member of a .NET class. This is usually adequate, but an alternative syntax is
provided to cater for classes that contain members that differ only by case.
The alternative uses a quoted string. For example, STR%'Length' or
STR%"Length". Only literal strings are permitted in this context. Character
expressions and parameters cannot be used.
.NET classes can have both private and public data members and only public
data members can be accessed directly from outside of the class (private
members can only be accessed by and via the given methods of the class).