Selbstreferenz mit Functional Classes in Gupta

Mit Gupta Team Developer lassen sich Functional Class Datentypen (UDV) erstellen – vergleichbar mit Klassen in C# oder Java. Im Unterschied zu den genannten Frameworks sind Variablen, die auf diesen Datentypen basieren, bei Gupta im Normalfall nicht nur deklariert sondern auch instantiiert. Das hat einen großen positiven Effekt: Man vermeidet den in C# und Java recht verbreiteten Runtimefehler „NullReferenceException“.

Beispiel C#

class SomeClass
{
        public Int32 someMember;
}
public void SomeMethod()
{
    SomeClass someObject;
        // NullReferenceException
    someObject.someMember = 7;

        // this works
    someObject = new SomeClass();
    someObject.someMember = 7;

}

Beispiel Gupta

Functional Class: SomeClass
    Instance Variables:
        Number: nSomeMember

Function: SomeFunction
    Local variables:
        SomeClass: someObject
    Actions:
        ! this works
        Set someObject.nSomeMember = 7

Gupta instantiiert die Klasse in dem Moment, in dem die Funktion SomeFunction() aufgerufen wird.

Dieses Standardverhalten hat aber auch einen Nachteil: Die Klasse (UDV) SomeClass kann sich selbst nicht (ohne weiteres) als Instanzvariable enthalten:

Functional Class: SomeClass
 Instance Variables:
     ! results in compile error: Circularly defined class.
     SomeClass: cSomeChild

Denn sobald SomeClass instantiiert würde, würde auch dessen Instance Variable cSomeChild instantiiert, anschließend dessen Instance Variable cSomeChild usw.

Dasselbe Problem tritt auf, wenn Class1 eine Instanzvariable vom Typ Class2 besitzt und Class2 eine von Class1.

Aber es gibt eine fast nicht dokumentierte Möglichkeit, eben doch solche Konstrukte zu erstellen: Indem man die UDV in der Deklaration auf OBJ_Null setzt:

Functional Class: SomeClass
 Instance Variables:
     SomeClass: cSomeChild = OBJ_Null

Ein paar Anmerkungen dazu:

  • Ich habe diese Möglichkeit zufällig an einer einzigen Stelle in der Hilfedatei von Gupta entdeckt: Als Beispielcode bei der Beschreibung des Befehls SalObjIsNull.
  • Nur UDVs können bei der Deklaration festgelegt werden. Bei Number, String, DateTime etc. lässt der TD das leider nicht zu. Immerhin soll mit TD 6.3 eine Konstruktor-Funktion für UDVs kommen, in denen man u.a. Werte für Instanzvariablen festlegen kann.
  • Wenn man die UDV cSomeChild verwenden möchte, muss man vorher entweder eine andere, bereits bestehende Instanz desselben oder abgeleiteten Typs zuweisen oder mit per new-Befehl eine Instanz erzeugen:
Set cSomeChild = new SomeClass

Anwendungsmöglichkeiten

Es gibt eine Menge Szenarien, in denen es äußerst nützlich oder sogar notwendig ist, verschachtelte Klassen zu verwenden:

  • Abbildung von hierarchischen Datenstrukturen, wie z.B. XML-Dokumente oder überhaupt alle Datenstrukturen, die man in TreeViews mit mehr als einer Ebene darstellen möchte oder kann.
  • Doppelt verknüpfte Listenstrukturen
  • Publish- Subscriber-Klassen, die wechselseitig verknüpft werden
  • Baumstrukturen – z.B. Red-Black-Index-Bäume

Viel Spaß beim Experimentieren.

Happy coding.

Advertisements

Über thomasuttendorfer
Ich bin Entwicklungsleiter bei der Softwarefirma [ frevel & fey ] in München. Wir entwickeln Business-Software für Verlage und verwenden dafür den Gupta Team-Developer sowie Visual Studio.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: