Hallo Leute,
gibt es vielleicht eine Möglichkeit in einer vorhandenen Klasse dynamisch eine zusetzliche Variable zu erzeugen, damit ich die z.B. mit oTest:cTest ansprechen kann. Da in meinem Programm ständig die globalen Einstellun gen wachsen, die ich mit Public-Variablen deklarieren muss, wollte ich eine Standartklasse haben, die ich dynamisch erweitern kann, ohne jedes mal die Klasse anpassen zu müssen.
Eine Lösung für die Speicherung in einem Array in der Klasse habe ich schon, nur der Aufruf wie im oberen Beispiel gefällt mir besser.
Es sollte so funktionieren:
oTest:cTest := "Test"
? oTest:cTest
Wenn die Variable nicht existiert, muss die erzeugt werden.
Dynamische Membervariablen erzeugen
Moderator: Moderatoren
-
- Rekursionen-Architekt
- Beiträge: 128
- Registriert: Mi, 26. Okt 2005 18:41
- Wohnort: Berlin
- Kontaktdaten:
Hallo Andreas,
so müßte es gehen:
Hier noch die Funktion MyGlobVar():
Vor jeder Zuweisung oder Abfrage mußt Du allerdings sicherstellen, daß die betreffende MemberVar existiert, wenn nicht mußt Du MyGlobVar um diese Membervar ergänzen. Das kannst Du z.B. so vornehmen:
Ab Xbase 1.9 kannst Du auf CheckMemberVar() auch verzichten und diese direkt in die Class integrieren, da erfolglose Zugriffe und Zuweisungen an nicht existierende Membervars durch die (undokumentierten) Methodenabgefangen werden. Dort mußt Du dann - analog zu CheckMemerVar() entsprechende Massnahmen einleiten, so daß Zuweisungen an die Instanz dann tatsächlich so möglich wären wie Du es beschrieben hast - ohne Rücksicht auf Existenz oder Nichtexistenz einer Membervar.
Es wäre interessant, das mal auszuprobieren. Wenn Du also Zeit hast ...
Ich kann mir allerdings nur schwerlich Rahmenbedingungen vorstellen, bei denen dieser Ansatz zur Verwaltung globaler Variablen strategische Vorteile bringt. Was willst Du denn damit machen?
Gruß
Olaf870
so müßte es gehen:
Code: Alles auswählen
PROC MAIN ()
#include 'class.ch'
aMyGlobVarNames := {}
aMyGlobVar := {}
// Hier addierst Du alle deine Vars in 2 Arrays
aadd( aMyGlobVarNames , { "cTest", CLASS_EXPORTED } ) // {VarNamen, DESCRIPTOR }
aadd( aMyGlobVar , "Test" ) // Werte
/*
usw. bis zu letzten Var
*/
MyGlobVar := MyGlobVar( aMyGlobVarNames, aMyGlobVar )
// Dann hast Du, was Du willst:
? MyGlobVar:cText // -> "Test"
RETURN
Code: Alles auswählen
func MyGlobVar( aMyGlobVarNames, aMyGlobVar )
LOCAL II
IF ClassObject( 'GlobVar' ) == NIL
ClassCreate( 'GlobVar', , aMyGlobVarNames ) // Definieren der Class
ENDIF
MyGlobVar := ClassObject( 'GlobVar' ):new() // Instanz erzeugen
FOR ii:=1 TO Len( aMyGlobVar )
MyGlobVar:&(aMyGlobVarNames[ii,1]) := aMyGlobVar [ii, 2 ] // Zuweisung der Werte
NEXT
return GlobVar
Code: Alles auswählen
FUNC CheckMemberVar( MyGlobVar, cVarName )
LOCAL aMyGlobVar, aMyGlobVarName, aXppIVars, II
IF !ismemberVar( MyGlobVar, cVarName ) //
aMyGlobVar := {}
aMyGlobVarName := {}
aXppIVars := MyGlobVar:classDescribe( CLASS_DESCR_MEMBERS )
FOR ii:=1 TO Len( aXppIvars )
// Hier merst Du dir alle Vars der Class GlobVar
aadd( aMyGlobVarNames, { aXppIvars[ii, CLASS_MEMBER_NAME ], CLASS_EXPORTED } )
aadd( aMyGlobVar, GlobVar:&(aMyGlobVarNames[ii,1]) )
NEXT
// Und addierst deine neue Var hinzu:
aadd( aMyGlobVarNames, { cVarName, CLASS_EXPORTED } ); aadd( aMyGlobVar , NIL )
ClassDestroy( GlobVar ) // Patz machen
// Hier ist dann die neue Class mit einem neuen Member cVarName
MyGlobVar := MyGlobVar( aMyGlobVarNames, aMyGlobVar )
ENDIF
RETURN MyGlobVar
Code: Alles auswählen
METHOD getNoIVar
METHOD setNoIVar
Es wäre interessant, das mal auszuprobieren. Wenn Du also Zeit hast ...
Ich kann mir allerdings nur schwerlich Rahmenbedingungen vorstellen, bei denen dieser Ansatz zur Verwaltung globaler Variablen strategische Vorteile bringt. Was willst Du denn damit machen?
Gruß
Olaf870
- andreas
- Der Entwickler von "Deep Thought"
- Beiträge: 1902
- Registriert: Mi, 28. Sep 2005 10:53
- Wohnort: Osnabrück
- Hat sich bedankt: 4 Mal
- Kontaktdaten:
Hallo Olaf,
danke für die Antwort. Ich glaube aber, dass es hiermit für die 1.82 Version zu kompliziert wird und sich nicht lohnen würde. Ich muss dann vielleicht erstmal bei meiner Wörterbuchklasse bleiben.
Wahrscheinlich muss ich doch einzelne Klassen einsetzen, um späteren Umstieg auf so eine Standart-Klasse zu erleichern.
danke für die Antwort. Ich glaube aber, dass es hiermit für die 1.82 Version zu kompliziert wird und sich nicht lohnen würde. Ich muss dann vielleicht erstmal bei meiner Wörterbuchklasse bleiben.
Ich habe unter einer Oberfläche alle irgendwann bei uns in der Firma eingesetzte Programme vereinigt. Das ist aber auch noch nicht alles. Das Programm wächst immer weiter. Dabei muss ich mehr für die standartisierung sorgen. Es gibt immer mehr Einstellungen, auf die ich von unterschiedliechen Modulen zugreifen muss. Dabei kann ich diese Einstellungen auch auf die Gruppen aufteilen. Damit es nicht so viele Public-Variablen gibt, dachte ich, dass es sinnvoll wäre, so eine Klasse zu erstellen, die alle Variablen einer gruppe erhält. Da es aber mehrere Gruppen gibt, wollte ich nicht für jede Gruppe eine Klasse schreiben und dachte an so eine Standart-Klasse. Dann habe ich eine Wörterbuchklasse geschrieben, wo die Variablen in einem Array aufbewahrt werden. Diese hat aber ein Nacteil: ich muss bei jedem Aufruf einer Get-Methode immer als Parameter den Namen der Variablen übergeben, was meiner Meinung nach die Grösse der EXE-Datei beeinflussen wird.Ich kann mir allerdings nur schwerlich Rahmenbedingungen vorstellen, bei denen dieser Ansatz zur Verwaltung globaler Variablen strategische Vorteile bringt. Was willst Du denn damit machen?
Wahrscheinlich muss ich doch einzelne Klassen einsetzen, um späteren Umstieg auf so eine Standart-Klasse zu erleichern.