Hallo zusammen,
bin gerade dabei eine Methode zu schreiben, die den "Basistyp" für einen gegebenen Array-Typen ausgibt. Beispiel: Bei
array of Integer
soll
tkInteger (TTypeKind) herauskommen bzw. eine Referenz auf
TypeInfo(Integer)
. Hier mal die aktuelle Methode:
Delphi-Quellcode:
function GetArrayBaseType(const ArrayTypeInfo: PTypeInfo; out BaseTypeKind: TTypeKind; out BaseTypeInfo: PTypeInfo): Boolean; overload;
var
TD : PTypeData;
BaseType : PTypeInfo;
begin
if (ArrayTypeInfo = nil) or (not (ArrayTypeInfo.Kind in [tkArray, tkDynArray])) then
Exit(False);
TD := GetTypeData(ArrayTypeInfo);
if (ArrayTypeInfo.Kind = tkArray) then
begin
if (TD.ArrayData.ElType = nil) or (TD.ArrayData.ElType^ = nil) then
Exit(False);
BaseType := TD.ArrayData.ElType^;
end
else begin
if ((TD.elType = nil) or (TD.elType^ = nil)) and ((TD.elType2 = nil) or (TD.elType2^ = nil)) then
Exit(False);
if ((TD.elType = nil) or (TD.elType^ = nil)) then
BaseType := TD.elType2^
else
BaseType := TD.elType^;
end;
if (BaseType.Kind in [tkArray, tkDynArray]) then
Result := GetArrayBaseType(BaseType, BaseTypeKind, BaseTypeInfo)
else begin
BaseTypeKind := BaseType.Kind;
BaseTypeInfo := BaseType;
Result := True;
end;
end;
Und hier das kleine Testprogramm dazu:
Delphi-Quellcode:
function GetArrayBaseTypeInfo(
const ArrayTypeInfo: PTypeInfo): PTypeInfo;
overload;
var
TK : TTypeKind;
begin
if (
not GetArrayBaseType(ArrayTypeInfo, TK, Result))
then
raise Exception.Create('
Could not read base type info of given array.');
end;
type
TDynArray =
array of Integer;
TGenericArray = TArray<
String>;
TBlub = TArray<TArray<TArray<Variant>>>;
TMatrix =
array[0..3, 0..3]
of Extended;
THugeMatrix =
array[0..3, 0..3]
of array[0..3, 0..3]
of Char;
TDynMatrixA =
array of array[0..3, 0..3]
of Int64;
TDynMatrixB =
array[0..3, 0..3]
of array of array[0..3, 0..3]
of Int64;
begin
Writeln(GetArrayBaseTypeInfo(TypeInfo(TDynArray)).
Name);
Writeln(GetArrayBaseTypeInfo(TypeInfo(TGenericArray)).
Name);
Writeln(GetArrayBaseTypeInfo(TypeInfo(TMatrix)).
Name);
Writeln(GetArrayBaseTypeInfo(TypeInfo(THugeMatrix)).
Name);
// <- hier hagelt es dann eine Exception
Writeln(GetArrayBaseTypeInfo(TypeInfo(TBlub)).
Name);
Writeln(GetArrayBaseTypeInfo(TypeInfo(TDynMatrixA)).
Name);
Writeln(GetArrayBaseTypeInfo(TypeInfo(TDynMatrixB)).
Name);
Das Programm läuft bis zum vorletzten Schritt, der ein "Mixed" Array (hier TDynMatrixA) behandelt, bestehend aus einem statischen und einem dynamischen Teil. Der erste Schritt in der Rekursion von GetArrayBaseType scheitert schon, da GetTypeData() quasi nichts sinnvolles an Daten liefert, siehe Screenshot. Nimmt der Compiler bei sowas interne Optimierungen vor, sodass ich via
RTTI hier nicht wirklich was ausrichten kann? Oder woher könnte das Problem sonst noch kommen? Gibt es vielleicht einen anderen Weg an den Basistyp eines Arrays zu gelangen? Kann ja auch gut sein, dass ich hiermit auf dem Holzpfad bin...
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)