TypeInfo (Type) gibt die Information über den angegebenen Typ zurück. Gibt es eine Möglichkeit, die Typinformation einer Variablen zu kennen?
%Vor%Dieser Code gibt zurück:
[DCC-Fehler] Unit1.pas (354): E2133 TYPINFO-Standardfunktion erwartet eine Typkennung
Ich weiß, dass eine nicht instantiierte Variable nur eine Zeigeradresse ist. Zur Kompilierzeit analysiert der Compiler und führt die Typsicherheitsprüfung durch.
Gibt es zur Laufzeit eine Möglichkeit, etwas mehr über ein var zu erfahren und nur seine Adresse zu übergeben?
Nein.
Erstens gibt es keine "nicht-instantiierte Variable". Sie instanziieren es, indem Sie einfach seinen Namen und Typ in Ihre Quelldatei eingeben.
Zweitens wissen Sie bereits alles über eine Variable, indem Sie sie in Ihrem Quellcode betrachten. Die Variable hört auf zu existieren , sobald Ihr Programm kompiliert wurde. Danach sind es nur noch Bits.
Ein Zeiger hat nur einen Typ zur Kompilierzeit. Zur Laufzeit ist alles, was an dieser Adresse ausgeführt werden kann, bereits festgelegt. Der Compiler überprüft dies, wie Sie bereits angemerkt haben. Das Überprüfen des Typs einer Variablen zur Laufzeit ist nur in Sprachen nützlich, in denen sich der Typ einer Variablen ändern kann, wie in dynamischen Sprachen. Das nächste Delphi kommt mit seinem Variant
-Typ. Der Typ der Variablen ist immer Variant
, aber Sie können viele Arten von Werten darin speichern. Um herauszufinden, was es enthält, können Sie die Funktion VarType
verwenden.
Immer wenn Sie TypeInfo
verwenden möchten, um die Typinformationen des mit einer Variablen verknüpften Typs abzurufen, können Sie auch direkt den Typ angeben, an dem Sie interessiert sind. Wenn sich die Variable im Geltungsbereich befindet, können Sie ihre Deklaration suchen und den deklarierten Typ in Ihrem Aufruf von TypeInfo
verwenden.
Wenn Sie eine beliebige Adresse an eine Funktion übergeben wollen und diese Funktion die Typinformation für sich selbst entdecken lassen, haben Sie kein Glück. Sie müssen stattdessen den Wert PTypeInfo
als zusätzlichen Parameter übergeben. Das machen alle integrierten Delphi-Funktionen. Wenn Sie beispielsweise New
für eine Zeigervariable aufrufen, fügt der Compiler einen zusätzlichen Parameter ein, der den Wert PTypeInfo
für den Typ enthält, den Sie zuweisen. Wenn Sie SetLength
für ein dynamisches Array aufrufen, fügt der Compiler einen PTypeInfo
-Wert für den Array-Typ ein.
Die Antwort, die Sie gaben schlägt vor, dass Sie nach etwas anderem suchen, als nach was Sie verlangten. Angesichts Ihrer Frage dachte ich, Sie suchten nach einer hypothetischen Funktion, die diesen Code erfüllen könnte:
%Vor% Nutzen wir die IsClass
und IsObject
Funktionen aus der JCL , um diese Funktion zu erstellen:
Es wird offensichtlich nicht für S
oder Instance
oben funktionieren, aber lass uns sehen, was mit Obj
passiert:
Das sollte eine Zugriffsverletzung geben. Obj
hat keinen Wert, also lesen IsClass
und IsObject
beide eine nicht angegebene Speicheradresse, wahrscheinlich keine, die zu Ihrem Prozess gehört. Sie haben nach einer Routine gefragt, die die Adresse einer Variablen als Eingabe verwendet, aber die bloße Adresse ist nicht genug.
Sehen wir uns jetzt an, wie sich IsClass
und IsObject
wirklich verhalten. Diese Funktionen nehmen einen willkürlichen Wert an und prüfen, ob der Wert wie aussieht, es könnte ein Wert der gegebenen Art sein, entweder Objekt (Instanz) oder Klasse. Benutze es so:
Beachten Sie, dass die Funktionen Ihnen nichts über die Variablen sagen, nur über die Werte , die sie enthalten. Ich würde diese Funktionen also nicht wirklich in Betracht ziehen, um die Frage zu beantworten, wie man Typinformationen über eine Variable erhält.
Außerdem haben Sie gesagt, dass Sie über die Variable nur die Adresse wissen. Die gefundenen Funktionen nehmen nicht die Adresse einer Variablen an. Sie nehmen den Wert einer Variablen. Hier ist eine Demonstration:
%Vor%Sie könnten einwenden, dass ich diese Funktionen missbrauche, indem ich offensichtlich Müll in sie übergebe. Aber ich denke, das ist die einzige Art, wie es sinnvoll ist, über dieses Thema zu sprechen. Wenn Sie wissen, dass Sie keine Garbage-Werte haben werden, brauchen Sie die gewünschte Funktion sowieso nicht, weil Sie bereits genug über Ihr Programm wissen, um echte Typen für Ihre Variablen zu verwenden.
Insgesamt stellen Sie die falsche Frage. Anstatt zu fragen, wie Sie den Typ einer Variablen oder den Typ eines Wertes im Speicher bestimmen, sollten Sie sich fragen, wie Sie sich an die Stelle begeben haben, an der Sie die Typen Ihrer Variablen und Ihrer Daten nicht kennen / strong>.
Nicht, dass ich davon weiß. Sie können RTTI (Run Time Type Information) für veröffentlichte Eigenschaften einer Klasse abrufen, aber nicht für "normale" Variablen wie Strings und Integer und so weiter. Die Information ist einfach nicht da.
Außerdem können Sie eine Variable nur übergeben, ohne einen Typ zu übergeben, indem Sie entweder einen generischen TObject-Parameter, einen generischen Typ (D2008, wie in) oder einen untypisierten Parameter verwenden. Ich kann mir keinen anderen Weg vorstellen, wie ich es weitergeben könnte.